diff --git a/INSTALL FUCKING READ THIS.txt b/INSTALL FUCKING READ THIS.txt
deleted file mode 100644
index 6d5442bd7..000000000
--- a/INSTALL FUCKING READ THIS.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-INSTALL:
-
-MAIN GMOD DIRECTORY:
-
-Scripts
-Particles
-
-
-
------------------------
-IF YOU WANT ACF POWERED STUFF TO GO MORE REALISTIC SPEEDS:
-
-Put these two lines in your server's SERVER.CFG
-
-
-lua_run local tbl = physenv.GetPerformanceSettings() tbl.MaxAngularVelocity = 30000 physenv.SetPerformanceSettings(tbl)
-
-lua_run local tbl = physenv.GetPerformanceSettings() tbl.MaxVelocity = 20000 physenv.SetPerformanceSettings(tbl)
-
-
-These lines will raise the angular velocity limit (wheels spinning) and forward speed limit
-
-Default gmod settings are crap and your small wheel acf-powered junk will go pretty fucking slow
diff --git a/README b/README
deleted file mode 100644
index 82bbf6163..000000000
--- a/README
+++ /dev/null
@@ -1,5 +0,0 @@
-# Advanced Combat Framework
-
-The Advanced Combat Framework is a [Garry's Mod][] addon which creates a balanced, realistic and fun to play combat damage system, simulating projectiles, armor and explosions, as well as engines and gearboxes.
-
-[Garry's Mod]:
diff --git a/README.md b/README.md
new file mode 100644
index 000000000..0df9269cd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,14 @@
+# Armoured Combat Framework
+
+The Armoured Combat Framework is a [Garry's Mod][] addon which creates a balanced, realistic and fun to play combat damage system, simulating projectiles, armor and explosions, as well as engines and gearboxes.
+
+IF YOU ARE HAVING INSTALLATION PROBLEMS, PLEASE POST ON THE FACEPUNCH ACF THREAD, NOT ON GITHUB. Please only create an issue on github if you've found a bug, or have a suggestion. The [FP forum ACF thread][] is a good place for general ACF conversation, suggestions, and help requests.
+
+When submitting a new issue or suggestion to [ACF Issues][] page, please double-check that someone else hasn't brought it up yet. Be sure to check closed issues as well. Common suggestions that have already come up are turbos, propellers, cannon sizes, and engines.
+
+Be sure to check out the [ACF Wiki][] for more ACF related information.
+
+[Garry's Mod]:
+[FP forum ACF thread]:
+[ACF Issues]:
+[ACF Wiki]:
\ No newline at end of file
diff --git a/acf-logo.png b/acf-logo.png
new file mode 100644
index 000000000..e32bb480e
Binary files /dev/null and b/acf-logo.png differ
diff --git a/addon.txt b/addon.txt
deleted file mode 100644
index f518e4fa0..000000000
--- a/addon.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-"AddonInfo"
-{
- "name" "Armored Combat Framework"
- "version" "v2.0"
- "up_date" "Feb 2011"
- "author_name" "Kafouille"
- "author_email" "Kafouille@gmail.com"
-
- "info" "A damage system based on prop size and weight, with customizable weapons"
-
- "override" "0"
-}
\ No newline at end of file
diff --git a/changelog.txt b/changelog.txt
index 0f1c21218..0057b23bf 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,221 +1,143 @@
-r01
-Guns :
-
---The guns "Ammo" input now only affects the next round to be loaded, the current round stays in the gun unless specifically unloaded or fired
-
---Added "Unload" wire input the guns, will cause them to send the round currently loaded back to the crate it came from and load a round from the currently selected crate
-
---Fixed the animation issues when linking an empty gun to a crate
-
---Fixed the sound issues with the cannons
-
-Menu :
-
---Added a changelog
-
---Fixed aspect ratio issues with the menu 3D display
-
---Added proper descriptions to the Engines and Gearboxes
-
-*r02
-Engines :
-
---Changed the existing engines to diesels, with corresponding sound
-
---Slightly upped the weight of both the 1.2l-i4 and 2l-i4
-
---Changes to the ideal RPM range of both the 1.2l-i4 and 2l-i4 :
- 12l : From 8000-10000RPM to 2000-4000RPM
- 2l : From 5000-7000RPM to 1800-3500RPM
-
---Increased the max torque of the 2l-i4 from 150n/m to 200n/m
-
---Lowered the max torque of the 15l-i4 from 5000n/m to 1800n/m
-
-*r03
-Guns :
-
---Reduced HE explosive power 25%
-
---Reduced mortar accuracy by half, and increased reload time by 50%
-
-Engines :
-
---Fixed a bug that made the engines apply twice as much power as their rated output to the wheels
-
-*r04
-Engines :
-
---Added Dual-Clutch gearboxes, that will allow you to use tank-like steering with only one gearbox
-
-*r05
-Engines :
-
---Added V8 lineup
---Increased engine volume
-
-*r06
-Engines :
--- Tuned the suck out of the 6.5L V8
-
-Gearboxes :
--- Added 6 speed lineup
-
-*r07
-Engines :
--- Added 3.5 & 8.7L diesel v8s, be sure to update your client
-
-*r07
-Engines :
--- Removed 3.5, 6.5, and 8.7L engines in favor of 9L petrol v8, inline 4/6 on their way to fill the gaps
-
-*r08
-Guns :
--- Added all new sounds for guns, soundscripting for them as well so they are audible at range
-Engines:
--- Added soundscripts and changed engine sounds accordingly
-
-*r09
-Guns :
--- HE occlusion issues are now fixed
-
-*r10
-Guns :
---Ammocrate armour is now calculated differently, only takeing the weight of the empty crate, without the ammo, into account.
-
---Ammo detonations occur differently, they are now based on the damage dealed to the crate compared to the size of the rounds in that crate. This makes it more difficult to detonate big rounds with MGs or rounds that just barely penetrated armour
-
-Interface :
---Changelog now appears upon selection of the ACF Menu
-
---Changelog revisions are now properly sorted
-
-*r11
-Gearboxes :
--- Added 4 & 6 speed inline gearboxes
-
-*r12
-Guns :
---IMPORTANT : Removed Ammo input on guns, replacing it is the Active input on crates. The gun will load rounds from any crate marked as Active, cycling them in the order they were linked in if more than one is Active. At least one crate has to be Active for the gun to be able to load ammo
-
---Added an AmmoCount output to the guns, showing the ammo count of all the crates currently Active
-
---Guns won't try to load from empty crates if any Active and linked crate still has ammo
-
-*r13
-Engines :
--- Added petrol Inline 4 series
-
-*r14
-Engines :
---Added Diesel & Petrol I6 series
-
---Retuned 9L v8; less torque, marginally more horsepower, and lighter in mass
-
-*r15
-Engines :
---Added Diesel v8 line, tweaked 20L to have a bit more torque and less horsepower, fixed some weights.
-
---Added new 6.5L diesel 6 sound.
-
-*r16
-Guns :
---Added a further penalty to damage for projectiles that have insignificant penetration compared to the armour it is hitting, to prevent the sandpaper effect
-
---HP is now calculated from surface aera, as to less favor large, blocky props
-
---Explosion damage on heavily armoured props is now much more dependent on fragmentation effects than on pure blast
-
---APHE loses penetration more quickly when HE content is added
-
---HEAT now correctly loses HE filler based on the cone volume
-
---HEAT penetration efficiency is slightly higher
-
---Fixed and issue with explosion damage and large, lightweight props
-
---Fixed a bug with ricochets where the bullets would continue flight from the wrong position
-
---Unlinking gearboxes from wheels doesn't cause duplication issues anymore
-
-Engines :
-
---Dual-clutch gearboxes now have their full rated torque per clutch, but will slip if more than the rating of a single clutch is applied to the whole gearbox
-
-*r17
-Gearboxes :
---Added line of 1 speed, heavy duty gearboxes aimed at aircraft and marine uses
-
-*r18
-Guns :
--- Added Heavy Machinegun series, this encompasses 20, 30, and 40mm MGs; they are light and fast firing, but suffer in accuracy and ballistic performance, as they are meant for aircraft
-
--- Changed the 12.7 and 14.5 to have lower rates of fire and are more accurate, as well as a new sound
-
-Engines :
---Balanced a lot of the petrol engines to be more stark from the diesels (diesels trade power for torque, and vice versa)
-
-*r19
-Guns :
---Fixed a crash if an ammocrate was spawned but couldn't containt at least one round of ammo
-
---Fixed a bug that caused HEAT slugs to have an insanely high chance to ricochet
-*r20
-Engines :
---Added lineup of Radials. No diesel ones, as they're not needed.
---Improved 9.2 V12's performance.
-
-*21
-Guns :
---Added proper HitBox support when firing at players and NPCs.
-
-Engines :
---Gearboxes can now link to other gearboxes, passing the power down the line
---Improved the behavior of the gearboxes at low gear ratios
---Fixed some weirdness with the torque distribution
---Added Gear Up / Gear Down inputs and Current Gear output to the Gearbox
---You can now update the Engines and Gearboxes with other types as long as they share the same model
-*r22
-General :
-
---New sounds for all the guns except the GL, guns are considerably louder now
---Added Autoloading cannons, these cannons fire magazines of ammo and then have a lengthy reload time. The new model for this is on the way
---Autocannons, RACs, and HMGs all now have "magazines", they will fire a burst and then reload
---Ammo crates will now hold more shells. As a result, your vehicles may be slightly heavier.
-This is in place so vehicles won't be such rolling powderkegs and have more of a chance of a penetration missing the ammunition inside, thus having a longer battle
-
-*r23
-
-Engines :
---Added V-Twin & Single cylinder engines, models courtesy of Gamerpaddy
-*r24
-
---ACF update checker by General Wrex
---Added a various assortment of common tools used with acf in attempt to keep all acf servers equal in terms of building and make it easier to use them (since most of them are on their own SVNs)
---SERVER OWNERS: Please remove the duplicate tools of the ones included in ACF if you already have them
-*r25
-
---Added ammunition blacklisting. MGs cannot fire HEAT and such.
---Added ammo disconnection after the weapon is 512 units away from its ammunition.
---Added prototype smoke launcher. Fires low velocity ground impact smoke shells to blind the enemy's line of sight. Reloads in 30 sec. The Smoke ammo can ONLY be used with the 40mm SL.
-
-*r26
---Fixed ammo menus, they have a scrollbar so those with less than X768 can see ammo info.
---Added Imperial outputs to engines (hp/lb ft)
---Admiral Wrex made both these awesome changes!
-*r27
-Engines :
---Added V6, Flat4, 6, and electric motors
---Retuned and rebalanced every motor, many motors were buffed (see SVN log for full list of changes)
---Added straight-through gearboxes
---Fixed flywheels not revving down properly, fixed throttling issues
---Off throttle volume cut 50%
---Proper code for electric/turbine torque curves
---Fucking awesome work by Wrex, Vii, and Gamerpaddy
-
-Misc :
-Nogravving dead props bug fixed
-*r30
---added working copy of ACF for Gmod 13
---this is the base of ACF for Gmod 13, not everything works, but its a starting point.
---applyoffsetforce seems to not be working properly, wheels are still removed because of spazzing.
\ No newline at end of file
+r600
+--For an extended version history, please visit the github changelog. https://github.com/nrlulz/ACF/commits/master
+
+*r604
+-Fixing revision number
+
+*r613
+- Merged in community changes from n0th1ng1996, PolySteam, shadow7483147 and with help from thegrb93. Thanks to all involved!
+- n0th1ng1996 (+ thegrb93):
+- Changed terminal ballistics for all rounds, introduced armour breaching (aka overmatching)
+- Added detonator bounce angles for explosive rounds except APHE.
+- Fixed HEAT bug, HEAT should now perform better.
+- Fixed entity:acfRoundType()
+- PolySteam:
+- Patched instant-reload bug.
+- shadow7483147:
+- Patched entity:acfFuelRequired()
+
+*r618
+- Merged in community changes from thegrb93. Thanks!
+- Fixed gearbox brake and added torque limit to prevent crashing/spontaneous deletion.
+- Optimized inertia calculation.
+
+*r621
+- Another change from thegrb93!
+- Fixed cases of infinite ricochet + suspected ammobox lag by limiting bullet ricochets to 3.
+
+*r625
+- Optimization by thegrb93:
+- Optimized gearbox torque application.
+
+*r627
+- Update courtesy of Red and Stovokor
+- Minor engine balancing
+- New small i2 petrol, small v4 diesel, med v4 diesel, med r7 diesel, large i2 diesel, large v6 diesel
+
+*r631
+- Update courtesy of thegrb93.
+- Increased anti-crash torque limit.
+
+*r633
+- Added 40mm CL, 6 round parentable smoke/flare launcher
+- Slightly buffed 40mm SL
+- Reds balancing stuff
+-- HEAT damage buffed
+-- HEAT damage decreased to fuel tanks
+-- HMG mag sizes increased 50%
+-- HMG reload time reduced by a couple seconds
+-- HMG other minor buffs
+-- RAC minor buffing and adjustments
+-- HRAC 20/30 magazine is 80/60 rounds respectively
+-- HRAC 20/30 reload is 4/6 seconds respectively
+-- HRAC slight pen buff
+-- HRAC minor fire rate nerf
+-- HRAC 30 weight reduced 1000 kg
+-- (blame HRAC changes on people mounting twin hracs and spraying nonstop)
+-- MG spread increased from 0.16 to 0.24
+-- AC spread decreased from 0.16 to 0.12
+-- SC spread decreased from 0.24 to 0.2
+-- Med v4 horsepower increased from 148 to 209
+
+*r634
+- Fixed an exploit with HP rounds
+- Modified crate ammo capacity to be a bit more consistent with model, courtesy of RDC
+- Slightly bumped up crate capacity bonus
+
+*r636
+- Fixed 140sc model size FINALLY, courtesy of Wizzard Lizzard and RDC
+
+*r637
+- Rebalanced all Ground Turbine engines, torque nerfed drastically but HP remaining the same.
+- GGTs now act more like piston engines in that they do not have instant torque from idle and require to sit at a certain rpm to be efficient.
+- Added some Lockheed Bitchin' Betty F22 sounds from Serif
+
+*r642
+- Added new E2 functions:
+-- ENTITY:acfReloadTime() - returns time to next shot of an ACF weapon
+-- ENTITY:acfMagReloadTime() - returns time it takes for an ACF weapon to reload magazine
+-- ENTITY:acfReloadProgress() - returns reload progress of an ACF weapon, useful for progress bars
+
+*r643
+- 'Fixed' killicons
+-- Added ACF.EnableKillicons global variable to enable or disable 'fixed' killicons
+-- Added ACF torch killicon
+-- Added acf_gun killicon
+- Fixed ACF_HE() argument naming
+- Fixed ACF_HE() usage in HE, APHE, HEAT ammunition
+
+*r645
+- new 140sc models were in the wrong folder
+
+*r653
+- Added jojobull's old wheel models
+- Added peniscolada's old steering wheel models
+- Optimized mem usage of tracing in ACF ballistics and HE damage
+- Replacing gun/engine sound with an empty path string will disable sound
+- ACF menu now shows spread for guns
+- Added e2func entity:acfGetLinkedWheels(), which returns any wheels directly linked to this or drivetrain children
+- Fixed first-load for guns at spawn
+-- Guns will now load their first round after spawning instantly, when a linked crate is activated
+-- Fixed first-load shotgunning exploit
+- Fixed crate over-capacity when unloading a gun too fast
+- Fixed unload skipping mag reload time
+- Fixed guns immediately showing full mag when starting reload
+- Fixed e2func isReloading
+- Fixed MASK_SHOT (ie passing through chain link fences) caliber being <3mm, not the intended <30mm
+- Added prop_dynamic to ballistics filter
+- Crates now cook off rounds from a random point inside the model
+- Crates with 1 round left will immediately detonate instead of cooking off the last shell
+-- Empty crates will still be safe, not dealing damage on detonation
+-- Single 120mm 1x1x6 crates are a lot more volatile now
+- Cookoff explosion now uses the avg pos of contributing crates, not origin of the first crate
+- HE damage will ignite 33% of destroyed props
+- Props destroyed by acf damage will also process their children, creating additional debris
+-- Amount of debris generated by processing children is limited to reduce lag
+-- Processed children that are ammo or fuel will immediately detonate
+-- AP damage that kills a parent will process children as if it was exploding
+--- This is purely for looks, as a directional spray of debris unrelated to the hit would look strange
+- Engines now include linked wheels as a startpoint for mass ratio calculation
+- Ballistics will not check visclips on makesphere props
+- Much more robust checking of basic legality
+-- Guns will also check seats for legality
+-- Random legality check every 5 to 25 seconds (avg 15s), with a 35 second lockout if not legal
+-- Ent overlay will tell you the remaining lockout time and what caused it
+-- Added a convar "acf_modelswap_legal", which defaults to 0 (not legal)
+- HEAT now has a crush speed that limits effective velocity
+-- From 800 m/s to 1200 m/s, filler used to power the heat jet is proportionally converted into HE charge
+-- Under 800 m/s, HEAT behaves normally; over 1200 m/s the HEAT jet cannot form and is purely HE
+- Buffed B6 med multifuel: 255 -> 286 hp. Renamed to 8.3L; this will break old dupes
+- Buffed B6 large: 604 -> 661 hp. Renamed to 15.8L; this will break old dupes
+- Buffed R7 petrols: health +50%, torque loss from damage reduced 20%
+- Buffed R7 small: 126 -> 189 hp
+- Buffed R7 med petrol: 228 -> 302 hp
+- Buffed R7 large: 600 -> 714 hp
+- Buffed V6P large: 800 -> 675 kg, adjusted powerband to increase torque
+- Buffed V6D large: 1200 -> 900 kg, adjusted powerband to drastically increase torque
+- Buffed V8D large: 1500 -> 1200 kg
+
+*r657
+- starfall update courtesy of cheese
+
+*r659
+- updated rocket effects courtesy of ghosteh
diff --git a/lua/ACF/Client/cl_ACFBallistics.lua b/lua/ACF/Client/cl_ACFBallistics.lua
deleted file mode 100644
index fdcd176a2..000000000
--- a/lua/ACF/Client/cl_ACFBallistics.lua
+++ /dev/null
@@ -1,28 +0,0 @@
-ACF.BulletEffect = {}
-
-function ACF_ManageBulletEffects()
-
- for Index,Bullet in pairs(ACF.BulletEffect) do
- ACF_SimBulletFlight( Bullet, Index ) --This is the bullet entry in the table, the omnipresent Index var refers to this
- end
-
-end
-hook.Add("Think", "ACF_ManageBulletEffects", ACF_ManageBulletEffects)
-
-function ACF_SimBulletFlight( Bullet, Index )
-
- local Time = CurTime()
- local DeltaTime = Time - Bullet.LastThink
-
- local Drag = Bullet.SimFlight:GetNormalized() * (Bullet.DragCoef * Bullet.SimFlight:Length()^2)/ACF.DragDiv
- --print(Drag)
-
- Bullet.SimPos = Bullet.SimPos + (Bullet.SimFlight * ACF.VelScale * DeltaTime) --Calculates the next shell position
- Bullet.SimFlight = Bullet.SimFlight + (Bullet.Accel - Drag)*DeltaTime --Calculates the next shell vector
-
- if Bullet and Bullet.Effect:IsValid() then
- Bullet.Effect:ApplyMovement( Bullet )
- end
- Bullet.LastThink = Time
-
-end
diff --git a/lua/ACF/Client/cl_ACFMenu_gui.lua b/lua/ACF/Client/cl_ACFMenu_gui.lua
deleted file mode 100644
index e4718b616..000000000
--- a/lua/ACF/Client/cl_ACFMenu_gui.lua
+++ /dev/null
@@ -1,441 +0,0 @@
-
-function PANEL:Init( )
-
- acfmenupanel = self.Panel
-
- // height
-
-
- self:SetTall( surface.ScreenHeight() - 120 )
-
- //Weapon Select
-
- self.WeaponSelect = vgui.Create( "DTree", self )
-
- self.WeaponData = ACF.Weapons
-
- local Classes = list.Get("ACFClasses")
- self.Classes = {}
- for ID,Table in pairs(Classes) do
- self.Classes[ID] = {}
- for ClassID,Class in pairs(Table) do
- Class.id = ClassID
- table.insert(self.Classes[ID], Class)
- end
- table.sort(self.Classes[ID], function(a,b) return a.id < b.id end )
- end
-
- local WeaponDisplay = list.Get("ACFEnts")
- self.WeaponDisplay = {}
- for ID,Table in pairs(WeaponDisplay) do
- self.WeaponDisplay[ID] = {}
- for EntID,Data in pairs(Table) do
- table.insert(self.WeaponDisplay[ID], Data)
- end
-
- if ID == "Guns" then
- table.sort(self.WeaponDisplay[ID], function(a,b) if a.gunclass == b.gunclass then return a.caliber < b.caliber else return a.gunclass < b.gunclass end end)
- else
- table.sort(self.WeaponDisplay[ID], function(a,b) return a.id < b.id end )
- end
-
- end
-
- local HomeNode = self.WeaponSelect:AddNode( "ACF Home" )
- HomeNode.mytable = {}
- HomeNode.mytable.guicreate = (function( Panel, Table ) ACFHomeGUICreate( Table ) end or nil)
- HomeNode.mytable.guiupdate = (function( Panel, Table ) ACFHomeGUIUpdate( Table ) end or nil)
- function HomeNode:DoClick()
- acfmenupanel:UpdateDisplay(self.mytable)
- end
- HomeNode.Icon:SetImage( "gui/silkicons/newspaper" )
-
- local RoundAttribs = list.Get("ACFRoundTypes")
- self.RoundAttribs = {}
- for ID,Table in pairs(RoundAttribs) do
- Table.id = ID
- table.insert(self.RoundAttribs, Table)
- end
- table.sort(self.RoundAttribs, function(a,b) return a.id < b.id end )
-
- local Guns = self.WeaponSelect:AddNode( "Guns" )
- for ClassID,Class in pairs(self.Classes["GunClass"]) do
-
- local SubNode = Guns:AddNode( Class.name or "No Name" )
-
- for Type, Ent in pairs(self.WeaponDisplay["Guns"]) do
- if Ent.gunclass == Class.id then
- local EndNode = SubNode:AddNode( Ent.name or "No Name" )
- EndNode.mytable = Ent
- function EndNode:DoClick()
- RunConsoleCommand( "acfmenu_type", self.mytable.type )
- acfmenupanel:UpdateDisplay( self.mytable )
- end
- EndNode.Icon:SetImage( "gui/silkicons/newspaper" )
- end
- end
-
- end
-
- local Ammo = self.WeaponSelect:AddNode( "Ammo" )
- for AmmoID,AmmoTable in pairs(self.RoundAttribs) do
-
- local EndNode = Ammo:AddNode( AmmoTable.name or "No Name" )
- EndNode.mytable = AmmoTable
- function EndNode:DoClick()
- RunConsoleCommand( "acfmenu_type", self.mytable.type )
- acfmenupanel:UpdateDisplay( self.mytable )
- end
- EndNode.Icon:SetImage( "gui/silkicons/newspaper" )
-
- end
-
- local Mobility = self.WeaponSelect:AddNode( "Mobility" )
- local Engines = Mobility:AddNode( "Engines" )
- local Gearboxes = Mobility:AddNode( "Gearboxes" )
- local EngineSubcats = {}
- for _, MobilityTable in pairs(self.WeaponDisplay["Mobility"]) do
- NodeAdd = Mobility
- if( MobilityTable.ent == "acf_engine" ) then
- NodeAdd = Engines
- elseif ( MobilityTable.ent == "acf_gearbox" ) then
- NodeAdd = Gearboxes
- end
- if((EngineSubcats["misce"] == nil) and (EngineSubcats["miscg"] == nil)) then
- EngineSubcats["misce"] = Engines:AddNode( "Miscellaneous" )
- EngineSubcats["miscg"] = Gearboxes:AddNode( "Miscellaneous" )
- end
- if(MobilityTable.category) then
- if(!EngineSubcats[MobilityTable.category]) then
- EngineSubcats[MobilityTable.category] = NodeAdd:AddNode( MobilityTable.category )
- end
- end
- end
-
- for MobilityID,MobilityTable in pairs(self.WeaponDisplay["Mobility"]) do
-
- local NodeAdd = Mobility
- if MobilityTable.ent == "acf_engine" then
- NodeAdd = Engines
- if(MobilityTable.category) then
- NodeAdd = EngineSubcats[MobilityTable.category]
- else
- NodeAdd = EngineSubcats["misce"]
- end
- elseif MobilityTable.ent == "acf_gearbox" then
- NodeAdd = Gearboxes
- if(MobilityTable.category) then
- NodeAdd = EngineSubcats[MobilityTable.category]
- else
- NodeAdd = EngineSubcats["miscg"]
- end
- end
-
- local EndNode = NodeAdd:AddNode( MobilityTable.name or "No Name" )
- EndNode.mytable = MobilityTable
- function EndNode:DoClick()
- RunConsoleCommand( "acfmenu_type", self.mytable.type )
- acfmenupanel:UpdateDisplay( self.mytable )
- end
- EndNode.Icon:SetImage( "gui/silkicons/newspaper" )
-
- end
-
-
-
- /*local Missiles = self.WeaponSelect:AddNode( "Missiles" )
- for MisID, MisTable in pairs(self.WeaponDisplay["Missiles"]) do
-
- local EndNode = Missiles:AddNode( MisTable.name or "No Name" )
-
- EndNode.mytable = MisTable
- function EndNode:DoClick()
- RunConsoleCommand( "acfmenu_type", self.mytable.type )
- acfmenupanel:UpdateDisplay( self.mytable )
- end
-
- EndNode.Icon:SetImage( "gui/silkicons/newspaper")
-
- end*/
- -- local Sensors = self.WeaponSelect:AddNode( "Sensors" )
- -- for SensorsID,SensorsTable in pairs(self.WeaponDisplay["Sensors"]) do
-
- -- local EndNode = Sensors:AddNode( SensorsTable.name or "No Name" )
- -- EndNode.mytable = SensorsTable
- -- function EndNode:DoClick()
- -- RunConsoleCommand( "acfmenu_type", self.mytable.type )
- -- acfmenupanel:UpdateDisplay( self.mytable )
- -- end
- -- EndNode.Icon:SetImage( "gui/silkicons/newspaper" )
-
- -- end
-
-end
-
-/*------------------------------------
- Think
-------------------------------------*/
-function PANEL:Think( )
-
-end
-
-function PANEL:UpdateDisplay( Table )
-
- RunConsoleCommand( "acfmenu_id", Table.id or 0 )
-
- --If a previous display exists, erase it
- if ( acfmenupanel.CustomDisplay ) then
- acfmenupanel.CustomDisplay:Clear(true)
- acfmenupanel.CustomDisplay = nil
- acfmenupanel.CData = nil
- end
- --Create the space to display the custom data
- acfmenupanel.CustomDisplay = vgui.Create( "DPanelList", acfmenupanel )
- acfmenupanel.CustomDisplay:SetSpacing( 5 )
- acfmenupanel.CustomDisplay:EnableHorizontal( false )
- acfmenupanel.CustomDisplay:EnableVerticalScrollbar( false )
- acfmenupanel.CustomDisplay:SetSize( acfmenupanel:GetWide(), acfmenupanel:GetTall() )
-
- if not acfmenupanel["CData"] then
- --Create a table for the display to store data
- acfmenupanel["CData"] = {}
- end
-
- acfmenupanel.CreateAttribs = Table.guicreate
- acfmenupanel.UpdateAttribs = Table.guiupdate
- acfmenupanel:CreateAttribs( Table )
-
- acfmenupanel:PerformLayout()
-
-end
-
-function PANEL:CreateAttribs( Table )
- --You overwrite this with your own function, defined in the ammo definition file, so each ammotype creates it's own menu
-end
-
-function PANEL:UpdateAttribs( Table )
- --You overwrite this with your own function, defined in the ammo definition file, so each ammotype creates it's own menu
-end
-
-function PANEL:PerformLayout()
-
- --Starting positions
- local vspacing = 10
- local ypos = 0
-
- --Selection Tree panel
- acfmenupanel.WeaponSelect:SetPos( 0, ypos )
- acfmenupanel.WeaponSelect:SetSize( acfmenupanel:GetWide(), 165 )
- ypos = acfmenupanel.WeaponSelect.Y + acfmenupanel.WeaponSelect:GetTall() + vspacing
-
- if acfmenupanel.CustomDisplay then
- --Custom panel
- acfmenupanel.CustomDisplay:SetPos( 0, ypos )
- acfmenupanel.CustomDisplay:SetSize( acfmenupanel:GetWide(), acfmenupanel:GetTall() - acfmenupanel.WeaponSelect:GetTall() - 10 )
- ypos = acfmenupanel.CustomDisplay.Y + acfmenupanel.CustomDisplay:GetTall() + vspacing
- end
-
-end
-
-function ACFHomeGUICreate( Table )
-
- if not acfmenupanel.CustomDisplay then return end
- --start version
-
- acfmenupanel["CData"]["VersionInit"] = vgui.Create( "DLabel" )
- versiontext = "Version\n\n".."SVN Version: "..ACF.CurrentVersion.."\nCurrent Version: "..ACF.Version
- acfmenupanel["CData"]["VersionInit"]:SetText(versiontext)
- acfmenupanel["CData"]["VersionInit"]:SizeToContents()
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"]["VersionInit"] )
-
-
- acfmenupanel["CData"]["VersionText"] = vgui.Create( "DLabel" )
-
- local color
- local versionstring
- if ACF.Version >= ACF.CurrentVersion then
- versionstring = "Up To Date"
- color = Color(0,225,0,255)
- else
- versionstring = "Out Of Date"
- color = Color(225,0,0,255)
-
- end
-
- acfmenupanel["CData"]["VersionText"]:SetText("ACF Is "..versionstring.."!\n\n\n\n")
- acfmenupanel["CData"]["VersionText"]:SetColor(color)
- acfmenupanel["CData"]["VersionText"]:SizeToContents()
-
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"]["VersionText"] )
- -- end version
-
- acfmenupanel:CPanelText("Header", "Changelog")
-
- acfmenupanel["CData"]["Changelist"] = vgui.Create( "DTree" )
- for Rev,Changes in pairs(acfmenupanel.Changelog) do
-
- local Node = acfmenupanel["CData"]["Changelist"]:AddNode( "Rev "..Rev )
- Node.mytable = {}
- Node.mytable["rev"] = Rev
- function Node:DoClick()
- acfmenupanel:UpdateAttribs( Node.mytable )
- end
- Node.Icon:SetImage( "gui/silkicons/newspaper" )
-
- end
- acfmenupanel.CData.Changelist:SetSize( acfmenupanel.CustomDisplay:GetWide(), 60 )
-
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"]["Changelist"] )
-
- acfmenupanel.CustomDisplay:PerformLayout()
-
- acfmenupanel:UpdateAttribs( {rev = table.maxn(acfmenupanel.Changelog)} )
-
-end
-
-function ACFHomeGUIUpdate( Table )
-
- acfmenupanel:CPanelText("Changelog", acfmenupanel.Changelog[Table["rev"]])
- acfmenupanel.CustomDisplay:PerformLayout()
-
-end
-
-function ACFChangelogHTTPCallBack(contents , size)
-
- local Temp = string.Explode( "*", contents )
- acfmenupanel.Changelog = {}
- for Key,String in pairs(Temp) do
- acfmenupanel.Changelog[tonumber(string.sub(String,2,3))] = string.Trim(string.sub(String, 5))
- end
- table.SortByKey(acfmenupanel.Changelog,true)
-
- local Table = {}
- Table.guicreate = (function( Panel, Table ) ACFHomeGUICreate( Table ) end or nil)
- Table.guiupdate = (function( Panel, Table ) ACFHomeGUIUpdate( Table ) end or nil)
- acfmenupanel:UpdateDisplay( Table )
-
-end
-http.Fetch("http://acf.googlecode.com/svn/trunk/changelog.txt", ACFChangelogHTTPCallBack, function() end)
-
-function PANEL:AmmoSelect( Blacklist )
-
- if not acfmenupanel.CustomDisplay then return end
- if not Blacklist then Blacklist = {} end
-
- if not acfmenupanel.AmmoData then
- acfmenupanel.AmmoData = {}
- acfmenupanel.AmmoData["Id"] = "Ammo2x4x4"
- acfmenupanel.AmmoData["Type"] = "Ammo"
- acfmenupanel.AmmoData["Data"] = acfmenupanel.WeaponData["Guns"]["12.7mmMG"]["round"]
- end
-
- --Creating the ammo crate selection
- acfmenupanel.CData.CrateSelect = vgui.Create( "DComboBox", acfmenupanel.CustomDisplay ) --Every display and slider is placed in the Round table so it gets trashed when selecting a new round type
- acfmenupanel.CData.CrateSelect:SetSize(100, 30)
- for Key, Value in pairs( acfmenupanel.WeaponDisplay["Ammo"] ) do
- acfmenupanel.CData.CrateSelect:AddChoice( Value.id , Key )
- end
- acfmenupanel.CData.CrateSelect.OnSelect = function( index , value , data )
- RunConsoleCommand( "acfmenu_id", data )
- end
- acfmenupanel.CData.CrateSelect:SetText(acfmenupanel.AmmoData["Id"])
- RunConsoleCommand( "acfmenu_id", acfmenupanel.AmmoData["Id"] )
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.CrateSelect )
-
- --Create the caliber selection display
- acfmenupanel.CData.CaliberSelect = vgui.Create( "DComboBox", acfmenupanel.CustomDisplay )
- acfmenupanel.CData.CaliberSelect:SetSize(100, 30)
- for Key, Value in pairs( acfmenupanel.WeaponDisplay["Guns"] ) do
- if( !table.HasValue( Blacklist, Value.gunclass ) ) then
- acfmenupanel.CData.CaliberSelect:AddChoice( Value.id , Key )
- end
- end
- acfmenupanel.CData.CaliberSelect.OnSelect = function( index , value , data )
- acfmenupanel.AmmoData["Data"] = acfmenupanel.WeaponData["Guns"][data]["round"]
- self:UpdateAttribs()
- self:UpdateAttribs() --Note : this is intentional
- end
- acfmenupanel.CData.CaliberSelect:SetText(acfmenupanel.AmmoData["Data"]["id"])
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.CaliberSelect )
-
-end
-
-function PANEL:AmmoSlider(Name, Value, Min, Max, Decimals, Title, Desc) --Variable name in the table, Value, Min value, Max Value, slider text title, slider decimeals, description text below slider
-
- if not acfmenupanel["CData"][Name] then
- acfmenupanel["CData"][Name] = vgui.Create( "DNumSlider", acfmenupanel.CustomDisplay )
- acfmenupanel["CData"][Name]:SetText( Title )
- acfmenupanel["CData"][Name]:SetMin( 0 )
- acfmenupanel["CData"][Name]:SetMax( 1000 )
- acfmenupanel["CData"][Name]:SetDecimals( Decimals )
- if acfmenupanel.AmmoData[Name] then
- acfmenupanel["CData"][Name]:SetValue(acfmenupanel.AmmoData[Name])
- end
- acfmenupanel["CData"][Name].OnValueChanged = function( slider, val )
- if acfmenupanel.AmmoData[Name] != val then
- acfmenupanel.AmmoData[Name] = val
- self:UpdateAttribs( Name )
- end
- end
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name] )
- end
- acfmenupanel["CData"][Name]:SetMin( Min )
- acfmenupanel["CData"][Name]:SetMax( Max )
- acfmenupanel["CData"][Name]:SetValue( Value )
-
- if not acfmenupanel["CData"][Name.."_text"] and Desc then
- acfmenupanel["CData"][Name.."_text"] = vgui.Create( "DLabel" )
- acfmenupanel["CData"][Name.."_text"]:SetText( Desc or "" )
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name.."_text"] )
- end
- acfmenupanel["CData"][Name.."_text"]:SetText( Desc )
- acfmenupanel["CData"][Name.."_text"]:SetSize( acfmenupanel.CustomDisplay:GetWide(), 10 )
- acfmenupanel["CData"][Name.."_text"]:SizeToContentsX()
-
-end
-
-function PANEL:AmmoCheckbox(Name, Title, Desc) --Variable name in the table, slider text title, slider decimeals, description text below slider
-
- if not acfmenupanel["CData"][Name] then
- acfmenupanel["CData"][Name] = vgui.Create( "DCheckBoxLabel" )
- acfmenupanel["CData"][Name]:SetText( Title or "" )
- acfmenupanel["CData"][Name]:SizeToContents()
- if acfmenupanel.AmmoData[Name] != nil then
- acfmenupanel["CData"][Name]:SetChecked(acfmenupanel.AmmoData[Name])
- else
- acfmenupanel.AmmoData[Name] = false
- end
- acfmenupanel["CData"][Name].OnChange = function( check, bval )
- acfmenupanel.AmmoData[Name] = bval
- self:UpdateAttribs( {Name, bval} )
- end
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name] )
- end
- acfmenupanel["CData"][Name]:SetText( Title )
-
-
- if not acfmenupanel["CData"][Name.."_text"] and Desc then
- acfmenupanel["CData"][Name.."_text"] = vgui.Create( "DLabel" )
- acfmenupanel["CData"][Name.."_text"]:SetText( Desc or "" )
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name.."_text"] )
- end
- acfmenupanel["CData"][Name.."_text"]:SetText( Desc )
- acfmenupanel["CData"][Name.."_text"]:SetSize( acfmenupanel.CustomDisplay:GetWide(), 10 )
- acfmenupanel["CData"][Name.."_text"]:SizeToContentsX()
-
-end
-
-function PANEL:CPanelText(Name, Desc)
-
- if not acfmenupanel["CData"][Name.."_text"] then
- acfmenupanel["CData"][Name.."_text"] = vgui.Create( "DLabel" )
- acfmenupanel["CData"][Name.."_text"]:SetText( Desc or "" )
- acfmenupanel["CData"][Name.."_text"]:SetWrap(true)
- acfmenupanel["CData"][Name.."_text"]:SetAutoStretchVertical( true )
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name.."_text"] )
- end
- acfmenupanel["CData"][Name.."_text"]:SetText( Desc )
- acfmenupanel["CData"][Name.."_text"]:SetSize( acfmenupanel.CustomDisplay:GetWide(), 10 )
- acfmenupanel["CData"][Name.."_text"]:SizeToContentsY()
-
-end
diff --git a/lua/ACF/Server/sv_ACFBallistics.lua b/lua/ACF/Server/sv_ACFBallistics.lua
deleted file mode 100644
index 152685b63..000000000
--- a/lua/ACF/Server/sv_ACFBallistics.lua
+++ /dev/null
@@ -1,149 +0,0 @@
-ACF.Bullet = {}
-ACF.CurBulletIndex = 0
-ACF.BulletIndexLimt = 1000 --The maximum number of bullets in flight at any one time
-
-function ACF_CreateBullet( BulletData )
-
- ACF.CurBulletIndex = ACF.CurBulletIndex + 1 --Increment the index
- if ACF.CurBulletIndex > ACF.BulletIndexLimt then
- ACF.CurBulletIndex = 1
- end
-
- local cvarGrav = GetConVar("sv_gravity")
- BulletData["Accel"] = Vector(0,0,cvarGrav:GetInt()*-1) --Those are BulletData settings that are global and shouldn't change round to round
- BulletData["LastThink"] = SysTime()
- BulletData["FlightTime"] = 0
- BulletData["TraceBackComp"] = 0
- if BulletData["Gun"]:IsValid() then --Check the Gun's velocity and add a modifier to the flighttime so the traceback system doesn't hit the originating contraption if it's moving along the shell path
- BulletData["TraceBackComp"] = BulletData["Gun"]:GetPhysicsObject():GetVelocity():Dot(BulletData["Flight"]:GetNormalized())
- if BulletData["Gun"].sitp_inspace then
- BulletData["Accel"] = Vector(0, 0, 0)
- BulletData["DragCoef"] = 0
- end
- --print(BulletData["TraceBackComp"])
- end
- BulletData["Filter"] = { BulletData["Gun"] }
- BulletData["Index"] = ACF.CurBulletIndex
-
- ACF.Bullet[ACF.CurBulletIndex] = table.Copy(BulletData) --Place the bullet at the current index pos
- ACF_BulletClient( ACF.CurBulletIndex, ACF.Bullet[ACF.CurBulletIndex], "Init" , 0 )
- ACF_CalcBulletFlight( ACF.CurBulletIndex, ACF.Bullet[ACF.CurBulletIndex] )
-
-end
-
-function ACF_ManageBullets()
-
- for Index,Bullet in pairs(ACF.Bullet) do
- ACF_CalcBulletFlight( Index, Bullet ) --This is the bullet entry in the table, the Index var omnipresent refers to this
- end
-
-end
-hook.Add("Think", "ACF_ManageBullets", ACF_ManageBullets)
-
-function ACF_RemoveBullet( Index )
-
- ACF.Bullet[Index] = nil
-
-end
-
-function ACF_CalcBulletFlight( Index, Bullet, BackTraceOverride )
-
- if not Bullet.LastThink then ACF_RemoveBullet( Index ) return end
- if BackTraceOverride then Bullet.FlightTime = 0 end
- local Time = SysTime()
- local DeltaTime = Time - Bullet.LastThink
-
- local Speed = Bullet.Flight:Length()
- local Drag = Bullet.Flight:GetNormalized() * (Bullet.DragCoef * Speed^2)/ACF.DragDiv
- Bullet.NextPos = Bullet.Pos + (Bullet.Flight * ACF.VelScale * DeltaTime) --Calculates the next shell position
- Bullet.Flight = Bullet.Flight + (Bullet.Accel - Drag)*DeltaTime --Calculates the next shell vector
- Bullet.StartTrace = Bullet.Pos - Bullet.Flight:GetNormalized()*math.min(ACF.PhysMaxVel*DeltaTime,Bullet.FlightTime*Speed-Bullet.TraceBackComp*DeltaTime)
-
- Bullet.LastThink = Time
- Bullet.FlightTime = Bullet.FlightTime + DeltaTime
-
- ACF_DoBulletsFlight( Index, Bullet )
-
-end
-
-function ACF_DoBulletsFlight( Index, Bullet )
-
- local FlightTr = { }
- FlightTr.start = Bullet.StartTrace
- FlightTr.endpos = Bullet.NextPos
- FlightTr.filter = Bullet.Filter
- local FlightRes = util.TraceLine(FlightTr) --Trace to see if it will hit anything
-
- if FlightRes.HitNonWorld then
- ACF_BulletPropImpact = ACF.RoundTypes[Bullet.Type]["propimpact"]
- local Retry = ACF_BulletPropImpact( Index, Bullet, FlightRes.Entity , FlightRes.HitNormal , FlightRes.HitPos , FlightRes.HitGroup ) --If we hit stuff then send the resolution to the damage function
- if Retry == "Penetrated" then --If we should do the same trace again, then do so
- ACF_BulletClient( Index, Bullet, "Update" , 2 , FlightRes.HitPos )
- ACF_DoBulletsFlight( Index, Bullet )
- --Msg("Retrying\n")
- elseif Retry == "Ricochet" then
- ACF_BulletClient( Index, Bullet, "Update" , 3 , FlightRes.HitPos )
- ACF_CalcBulletFlight( Index, Bullet, true )
- else --Else end the flight here
- ACF_BulletClient( Index, Bullet, "Update" , 1 , FlightRes.HitPos )
- ACF_BulletEndFlight = ACF.RoundTypes[Bullet.Type]["endflight"]
- ACF_BulletEndFlight( Index, Bullet, FlightRes.HitPos, FlightRes.HitNormal )
- end
- elseif FlightRes.HitWorld then --If we hit the world then try to see if it's thin enough to penetrate
- ACF_BulletWorldImpact = ACF.RoundTypes[Bullet.Type]["worldimpact"]
- local Retry = ACF_BulletWorldImpact( Index, Bullet, FlightRes.HitPos, FlightRes.HitNormal )
- if Retry == "Penetrated" then --if it is, we soldier on
- ACF_BulletClient( Index, Bullet, "Update" , 2 , FlightRes.HitPos )
- ACF_CalcBulletFlight( Index, Bullet, true ) --The world ain't going to move, so we say True for the backtrace override
- else --If not, end of the line, boyo
- ACF_BulletClient( Index, Bullet, "Update" , 1 , FlightRes.HitPos )
- ACF_BulletEndFlight = ACF.RoundTypes[Bullet.Type]["endflight"]
- ACF_BulletEndFlight( Index, Bullet, FlightRes.HitPos, FlightRes.HitNormal )
- end
- else --If we didn't hit anything, move the shell and schedule next think
- Bullet.Pos = Bullet.NextPos
- end
-
-end
-
-function ACF_BulletClient( Index, Bullet, Type, Hit, HitPos )
-
- if Type == "Update" then
- local Effect = EffectData()
- Effect:SetAttachment( Index ) --Bulet Index
- Effect:SetStart( Bullet.Flight/10 ) --Bullet Direction
- if Hit > 0 then -- If there is a hit then set the effect pos to the impact pos instead of the retry pos
- Effect:SetOrigin( HitPos ) --Bullet Pos
- else
- Effect:SetOrigin( Bullet.Pos )
- end
- Effect:SetScale( Hit ) --Hit Type
- util.Effect( "ACF_BulletEffect", Effect, true, true )
-
- else
- local Effect = EffectData()
- local Filler = 0
- if Bullet["FillerMass"] then Filler = Bullet["FillerMass"]*15 end
- Effect:SetAttachment( Index ) --Bulet Index
- Effect:SetStart( Bullet.Flight/10 ) --Bullet Direction
- Effect:SetOrigin( Bullet.Pos )
- Effect:SetMagnitude( Bullet["Crate"] ) --Encodes the crate the ammo originates from so clientside knows the crate from wich to pull ammo data
- Effect:SetScale( 0 )
- util.Effect( "ACF_BulletEffect", Effect, true, true )
-
- end
-
-end
-
-function ACF_BulletWorldImpact( Bullet, Index, HitPos, HitNormal )
- --You overwrite this with your own function, defined in the ammo definition file
-end
-
-function ACF_BulletPropImpact( Bullet, Index, Target, HitNormal, HitPos )
- --You overwrite this with your own function, defined in the ammo definition file
-end
-
-function ACF_BulletEndFlight( Bullet, Index, HitPos )
- --You overwrite this with your own function, defined in the ammo definition file
-end
-
diff --git a/lua/ACF/Server/sv_ACFBase.lua b/lua/ACF/Server/sv_ACFBase.lua
deleted file mode 100644
index 78ba47035..000000000
--- a/lua/ACF/Server/sv_ACFBase.lua
+++ /dev/null
@@ -1,248 +0,0 @@
-function ACF_Activate ( Entity , Recalc )
-
- --Density of steel = 7.8g cm3 so 7.8kg for a 1mx1m plate 1m thick
- if Entity.SpecialHealth then
- Entity:ACF_Activate( Recalc )
- return
- end
- local Size = Entity.OBBMaxs(Entity) - Entity.OBBMins(Entity)
- local Aera = ((Size.x * Size.y)+(Size.x * Size.z)+(Size.y * Size.z)) * 6.45 --Converting from square in to square cm, fuck imperial
- local Volume = Size.x * Size.y * Size.z * 16.38
- local Armour = Entity:GetPhysicsObject():GetMass()*1000 / Aera / 0.78 --So we get the equivalent thickness of that prop in mm if all it's weight was a steel plate
- local Health = Aera/ACF.Threshold --Setting the threshold of the prop aera gone
- local Percent = 1
-
- if Recalc then
- Percent = Entity.ACF.Health/Entity.ACF.MaxHealth
- end
- Entity.ACF = {}
- Entity.ACF.Health = Health * Percent
- Entity.ACF.MaxHealth = Health
- Entity.ACF.Armour = Armour * (0.5 + Percent/2)
- Entity.ACF.MaxArmour = Armour * ACF.ArmorMod
- Entity.ACF.Type = nil
- Entity.ACF.Mass = Entity:GetPhysicsObject():GetMass()
- Entity.ACF.Density = (Entity:GetPhysicsObject():GetMass()*1000)/Volume
-
- if Entity:IsPlayer() || Entity:IsNPC() then
- Entity.ACF.Type = "Squishy"
- elseif Entity:IsVehicle() then
- Entity.ACF.Type = "Vehicle"
- else
- Entity.ACF.Type = "Prop"
- end
-
-end
-
-function ACF_Check ( Entity )
-
- if ( IsValid(Entity) ) then
- if ( Entity:GetPhysicsObject():IsValid() and !Entity:IsWorld() and !Entity:IsWeapon() ) then
- local Class = Entity:GetClass()
- --print(Class)
- if ( Class != "gmod_ghost" and Class != "debris" and Class != "prop_ragdoll" and not string.find( Class , "func_" ) ) then
- if !Entity.ACF then
- ACF_Activate( Entity )
- elseif Entity.ACF.Mass != Entity:GetPhysicsObject():GetMass() then
- ACF_Activate( Entity , true )
- end
- return Entity.ACF.Type
- end
- end
- end
- return false
-
-end
-
-function ACF_Damage ( Entity , Energy , FrAera , Angle , Inflictor , Bone )
-
- local Activated = ACF_Check( Entity )
-
- if Entity.SpecialDamage then
- return Entity:ACF_OnDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
- elseif Activated == "Prop" then
-
- return ACF_PropDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
-
- elseif Activated == "Vehicle" then
-
- return ACF_VehicleDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
-
- elseif Activated == "Squishy" then
-
- return ACF_SquishyDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
-
- end
-
-end
-
-function ACF_CalcDamage( Entity , Energy , FrAera , Angle )
-
- local Armour = Entity.ACF.Armour/math.abs( math.cos(math.rad(Angle)) ) --Calculate Line Of Sight thickness of the armour
- local Structure = Entity.ACF.Density --Structural strengh of the material, derived from prop density, denser stuff is more vulnerable (Density is different than armour, calculated off real volume)
-
- local MaxPenetration = (Energy.Penetration / FrAera) * ACF.KEtoRHA --Let's see how deep the projectile penetrates ( Energy = Kinetic Energy, FrAera = Frontal aera in cm2 )
- --print(MaxPenetration)
- local Penetration = math.min( MaxPenetration , Armour ) --Clamp penetration to the armour thickness
-
- local HitRes = {}
- --BNK Stuff
- local dmul = 1
- if (ISBNK) then
- local cvar = GetConVarNumber("sbox_godmode")
-
- if (cvar == 1) then
- dmul = 0
- end
- end
- --SITP Stuff
- local var = 1
- if (ISSITP) then
- if(!Entity.sitp_spacetype) then
- Entity.sitp_spacetype = "space"
- end
- if(Entity.sitp_spacetype != "space" and Entity.sitp_spacetype != "planet") then
- var = 0
- end
- end
-
- HitRes.Damage = var * dmul * (Penetration/Armour)^2 * FrAera -- This is the volume of the hole caused by our projectile
- --print(HitRes.Damage)
- HitRes.Overkill = (MaxPenetration - Penetration)
- HitRes.Loss = Penetration/MaxPenetration
-
- return HitRes
-end
-
-function ACF_PropDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
-
- local HitRes = ACF_CalcDamage( Entity , Energy , FrAera , Angle )
-
- HitRes.Kill = false
- if HitRes.Damage >= Entity.ACF.Health then
- HitRes.Kill = true
- else
- Entity.ACF.Health = Entity.ACF.Health - HitRes.Damage
- Entity.ACF.Armour = Entity.ACF.MaxArmour * (0.5 + Entity.ACF.Health/Entity.ACF.MaxHealth/2) --Simulating the plate weakening after a hit
- end
-
- return HitRes
-
-end
-
-function ACF_VehicleDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
-
- local HitRes = ACF_CalcDamage( Entity , Energy , FrAera , Angle )
-
- local Driver = Entity:GetDriver()
- if Driver:IsValid() then
- Driver:TakeDamage( HitRes.Damage*40 , Inflictor )
- end
-
- HitRes.Kill = false
- if HitRes.Damage >= Entity.ACF.Health then
- HitRes.Kill = true
- else
- Entity.ACF.Health = Entity.ACF.Health - HitRes.Damage
- Entity.ACF.Armour = Entity.ACF.Armour * (0.5 + Entity.ACF.Health/Entity.ACF.MaxHealth/2) --Simulating the plate weakening after a hit
- end
-
- return HitRes
-end
-
-function ACF_SquishyDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
-
- local Size = Entity:BoundingRadius()
- local Mass = Entity:GetPhysicsObject():GetMass()
- local HitRes = {}
- local Damage = 0
- local Target = {ACF = {Armour = 0.1}} --We create a dummy table to pass armour values to the calc function
- if (Bone) then
-
- if ( Bone == 1 ) then --This means we hit the head
- Target.ACF.Armour = Mass*0.02 --Set the skull thickness as a percentage of Squishy weight, this gives us 2mm for a player, about 22mm for an Antlion Guard. Seems about right
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle ) --This is hard bone, so still sensitive to impact angle
- Damage = HitRes.Damage*20
- if HitRes.Overkill > 0 then --If we manage to penetrate the skull, then MASSIVE DAMAGE
- Target.ACF.Armour = Size*0.25*0.01 --A quarter the bounding radius seems about right for most critters head size
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
- Damage = Damage + HitRes.Damage*100
- end
- Target.ACF.Armour = Mass*0.065 --Then to check if we can get out of the other side, 2x skull + 1x brains
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle )
- Damage = Damage + HitRes.Damage*20
-
- elseif ( Bone == 0 or Bone == 2 or Bone == 3 ) then --This means we hit the torso. We are assuming body armour/tough exoskeleton/zombie don't give fuck here, so it's tough
- Target.ACF.Armour = Mass*0.08 --Set the armour thickness as a percentage of Squishy weight, this gives us 8mm for a player, about 90mm for an Antlion Guard. Seems about right
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle ) --Armour plate,, so sensitive to impact angle
- Damage = HitRes.Damage*5
- if HitRes.Overkill > 0 then
- Target.ACF.Armour = Size*0.5*0.02 --Half the bounding radius seems about right for most critters torso size
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
- Damage = Damage + HitRes.Damage*50 --If we penetrate the armour then we get into the important bits inside, so DAMAGE
- end
- Target.ACF.Armour = Mass*0.185 --Then to check if we can get out of the other side, 2x armour + 1x guts
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle )
-
- elseif ( Bone == 4 or Bone == 5 ) then --This means we hit an arm or appendage, so ormal damage, no armour
-
- Target.ACF.Armour = Size*0.2*0.02 --A fitht the bounding radius seems about right for most critters appendages
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 ) --This is flesh, angle doesn't matter
- Damage = HitRes.Damage*30 --Limbs are somewhat less important
-
- elseif ( Bone == 6 or Bone == 7 ) then
-
- Target.ACF.Armour = Size*0.2*0.02 --A fitht the bounding radius seems about right for most critters appendages
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 ) --This is flesh, angle doesn't matter
- Damage = HitRes.Damage*30 --Limbs are somewhat less important
-
- elseif ( Bone == 10 ) then --This means we hit a backpack or something
-
- Target.ACF.Armour = Size*0.1*0.02 --Arbitrary size, most of the gear carried is pretty small
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 ) --This is random junk, angle doesn't matter
- Damage = HitRes.Damage*2 --Damage is going to be fright and shrapnel, nothing much
-
- else --Just in case we hit something not standard
-
- Target.ACF.Armour = Size*0.2*0.02
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
- Damage = HitRes.Damage*30
-
- end
-
- else --Just in case we hit something not standard
-
- Target.ACF.Armour = Size*0.2*0.02
- HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
- Damage = HitRes.Damage*10
-
- end
-
- local dmul = 2.5
-
- --BNK stuff
- if (ISBNK) then
- if(Entity.freq and Inflictor.freq) then
- if (Entity != Inflictor) and (Entity.freq == Inflictor.freq) then
- dmul = 0
- end
- end
- end
-
- --SITP stuff
- local var = 1
- if(!Entity.sitp_spacetype) then
- Entity.sitp_spacetype = "space"
- end
- if(Entity.sitp_spacetype == "homeworld") then
- var = 0
- end
-
- Entity:TakeDamage( Damage * dmul * var , Inflictor )
-
- HitRes.Kill = false
- --print(Damage)
- --print(Bone)
-
- return HitRes
-end
diff --git a/lua/ACF/Server/sv_ACFDamage.lua b/lua/ACF/Server/sv_ACFDamage.lua
deleted file mode 100644
index 9c3b041f7..000000000
--- a/lua/ACF/Server/sv_ACFDamage.lua
+++ /dev/null
@@ -1,405 +0,0 @@
--- This file is meant for the advanced damage functions used by the Armored Combat Framework
-function ACF_HE( Hitpos , HitNormal , FillerMass, FragMass , Inflictor, NoOcc ) --HitPos = Detonation center, FillerMass = mass of TNT being detonated in KG, FragMass = Mass of the round casing for fragmentation purposes, Inflictor owner of said TNT
-
- local Power = FillerMass * ACF.HEPower --Power in KiloJoules of the filler mass of TNT
- local Radius = (FillerMass)^0.33*8*39.37 --Scalling law found on the net, based on 1PSI overpressure from 1 kg of TNT at 15m
- local MaxSphere = (4 * 3.1415 * (Radius*2.54 )^2) --Surface Aera of the sphere at maximum radius
- local Amp = math.min(Power/2000,50)
- util.ScreenShake( Hitpos, Amp, Amp, Amp/15, Radius*10 )
- --local Targets = ents.FindInSphere( Hitpos, Radius )
- local Targets = ents.GetAll()
- for k,v in pairs (Targets) do
- local epos = v:GetPos()
- if Hitpos:Distance(epos) > Radius then
- Targets[k] = nil
- end
- end
-
- local Fragments = math.max(math.floor((FillerMass/FragMass)*ACF.HEFrag),2)
- local FragWeight = FragMass/Fragments
- local FragVel = (Power*50000/FragWeight/Fragments)^0.5
- local FragAera = (FragWeight/7.8)^0.33
-
- local OccFilter = { NoOcc }
- local LoopKill = true
-
- while LoopKill and Power > 0 do
- LoopKill = false
- local PowerSpent = 0
- local Iterations = 0
- local Damage = {}
- local TotalAera = 0
- for i,Tar in pairs(Targets) do
- Iterations = i
- --Msg("Target : " ..Tar:GetClass().. "\n")
- if ( Tar.Entity != nil and Power > 0 and not Tar.Entity.Exploding ) then
- local Type = ACF_Check(Tar.Entity)
- if ( Type ) then
- local Hitat = nil
- if Type == "Squishy" then --A little hack so it doesn't check occlusion at the feet of players
- local Eyes = Tar.Entity:LookupAttachment("eyes")
- if Eyes then
- Hitat = Tar.Entity:GetAttachment( Eyes )
- if Hitat then
- --Msg("Hitting Eyes\n")
- Hitat = Hitat.Pos
- else
- Hitat = Tar:NearestPoint( Hitpos )
- end
- end
- else
- Hitat = Tar:NearestPoint( Hitpos )
- end
-
- local Occlusion = {}
- Occlusion.start = Hitpos
- Occlusion.endpos = Hitat + (Hitat-Hitpos):GetNormalized()*100
- Occlusion.filter = OccFilter
- Occlusion.mask = MASK_SOLID
- local Occ = util.TraceLine( Occlusion )
-
- if ( !Occ.Hit and Hitpos != Hitat ) then
- local Hitat = Tar.Entity:GetPos()
- local Occlusion = {}
- Occlusion.start = Hitpos
- Occlusion.endpos = Hitat + (Hitat-Hitpos):GetNormalized()*100
- Occlusion.filter = OccFilter
- Occlusion.mask = MASK_SOLID
- Occ = util.TraceLine( Occlusion )
- end
-
- if ( Occ.Hit and Occ.Entity:EntIndex() != Tar.Entity:EntIndex() ) then
- --print(Occ.Entity)
- elseif ( !Occ.Hit and Hitpos != Hitat ) then
- --print("No Hit")
- --print(Tar.Entity)
- --print((Hitpos - Hitat):Length())
- else
- Targets[i] = nil --Remove the thing we just hit from the table so we don't hit it again in the next round
- local Table = {}
- Table.Ent = Tar.Entity
- Table.Dist = Hitpos:Distance(Tar.Entity:GetPos())
- Table.Vec = (Tar.Entity:GetPos() - Hitpos):GetNormal()
- local Sphere = math.max(4 * 3.1415 * (Table.Dist*2.54 )^2,1) --Surface Aera of the sphere at the range of that prop
- Table.Aera = math.min((Tar.ACF.MaxHealth*ACF.Threshold)/Sphere,0.5)*MaxSphere --Project the aera of the prop to the aera of the shadow it projects at the explosion max radius
- table.insert(Damage, Table) --Add it to the Damage table so we know to damage it once we tallied everything
- TotalAera = TotalAera + Table.Aera
- end
- else
- Targets[i] = nil --Target was invalid, so let's ignore it
- table.insert( OccFilter , Tar.Entity )
- end
- end
- end
-
- for i,Table in pairs(Damage) do
-
- local Tar = Table.Ent
- local AeraFraction = Table.Aera/TotalAera
- local PowerFraction = Power * AeraFraction --How much of the total power goes to that prop
-
- local Blast = {}
- Blast.Momentum = PowerFraction/(math.max(1,Table.Dist/200)^0.05)
- Blast.Penetration = PowerFraction^ACF.HEBlastPen*Tar.ACF.MaxHealth
- local BlastRes = ACF_Damage ( Tar.Entity , Blast , Tar.ACF.MaxHealth , 0 , Inflictor ,0 )--Vel is just the speed of sound in air
- PowerSpent = PowerSpent + PowerFraction*BlastRes.Loss/2--Removing the energy spent killing props
-
- local FragHit = Fragments * AeraFraction
- local FragVel = math.max(FragVel - ( (Table.Dist/FragVel) * FragVel^2 * FragWeight^0.33/10000 )/ACF.DragDiv,0)
- local FragKE = ACF_Kinetic( FragVel , FragWeight*FragHit, 1500 )
- if FragHit < 0 then
- if math.Rand(0,1) > FragHit then FragHit = 1 else FragHit = 0 end
- end
-
- local FragRes = ACF_Damage ( Tar.Entity , FragKE , (FragWeight/7.8)^0.33*FragHit , 0 , Inflictor , 0 )
-
- if (BlastRes and BlastRes.Kill) or (FragRes and FragRes.Kill) then
- local Debris = ACF_HEKill( Tar.Entity , Table.Vec , PowerFraction )
- table.insert( OccFilter , Debris ) --Add the debris created to the ignore so we don't hit it in other rounds
- LoopKill = true
- else
- local phys = Tar.Entity:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:ApplyForceOffset( Table.Vec * PowerFraction * 100 , Hitpos ) --Assuming about a tenth of the energy goes to propelling the target prop (Power in KJ * 1000 to get J then divided by 10)
- end
- end
-
- end
- Power = math.max(Power - PowerSpent,0)
- end
-
-end
-
-function ACF_Spall( HitPos , HitVec , HitMask , KE , Caliber , Armour , Inflictor )
-
- if(!ACF.Spalling) then
- return
- end
- local TotalWeight = 3.1416*(Caliber/2)^2 * Armour * 0.00079
- local Spall = math.max(math.floor(Caliber*ACF.KEtoSpall),2)
- local SpallWeight = TotalWeight/Spall
- local SpallVel = (KE*2000/SpallWeight)^0.5/Spall
- local SpallAera = (SpallWeight/7.8)^0.33
- local SpallEnergy = ACF_Kinetic( SpallVel , SpallWeight, 600 )
-
- --print(SpallWeight)
- --print(SpallVel)
-
- for i = 1,Spall do
- local SpallTr = { }
- SpallTr.start = HitPos
- SpallTr.endpos = HitPos + (HitVec:GetNormalized()+VectorRand()/2):GetNormalized()*SpallVel
- SpallTr.filter = HitMask
-
- ACF_SpallTrace( HitVec , SpallTr , SpallEnergy , SpallAera , Inflictor )
- end
-
-end
-
-function ACF_SpallTrace( HitVec , SpallTr , SpallEnergy , SpallAera , Inflictor )
-
- local SpallRes = util.TraceLine(SpallTr)
-
- if SpallRes.Hit and ACF_Check( SpallRes.Entity ) then
-
- local Angle = ACF_GetHitAngle( SpallRes.HitNormal , HitVec )
- local HitRes = ACF_Damage( SpallRes.Entity , SpallEnergy , SpallAera , Angle , Inflictor, 0 ) --DAMAGE !!
- if HitRes.Kill then
- ACF_APKill( SpallRes.Entity , HitVec:GetNormalized() , SpallEnergy.Kinetic )
- end
- if HitRes.Overkill > 0 then
- table.insert( SpallTr.filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
- SpallEnergy.Penetration = SpallEnergy.Penetration*(1-HitRes.Loss)
- SpallEnergy.Momentum = SpallEnergy.Momentum*(1-HitRes.Loss)
- ACF_SpallTrace( HitVec , SpallTr , SpallEnergy , SpallAera , Inflictor )
- end
-
- end
-
-end
-
-function ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone ) --Simulate a round impacting on a prop
-
- local Angle = ACF_GetHitAngle( HitNormal , Bullet["Flight"] )
-
- local Ricochet = 0
- local MinAngle = math.min(Bullet["Ricochet"] - Speed/39.37/15,89) --Making the chance of a ricochet get higher as the speeds increase
- if Angle > math.random(MinAngle,90) and Angle < 89.9 then --Checking for ricochet
- Ricochet = (Angle/100) --If ricocheting, calculate how much of the energy is dumped into the plate and how much is carried by the ricochet
- Energy.Penetration = Energy.Penetration - Energy.Penetration*Ricochet/4 --Ricocheting can save plates that would theorically get penetrated, can add up to 1/4 rating
- end
- local HitRes = ACF_Damage ( Target , Energy , Bullet["PenAera"] , Angle , Bullet["Owner"] , Bone, 0 ) --DAMAGE !!
-
- ACF_KEShove(Target, HitPos, Bullet["Flight"]:GetNormal(), Energy.Kinetic*HitRes.Loss*1000*Bullet["ShovePower"] )
-
- if HitRes.Kill then
- local Debris = ACF_APKill( Target , (Bullet["Flight"]):GetNormalized() , Energy.Kinetic )
- table.insert( Bullet["Filter"] , Debris )
- end
-
- HitRes.Ricochet = false
- if Ricochet > 0 then
- Bullet["Pos"] = HitPos
- Bullet["Flight"] = (Bullet["Flight"]:GetNormalized() + HitNormal*(1-Ricochet+0.05) + VectorRand()*0.05):GetNormalized() * Speed * Ricochet
- HitRes.Ricochet = true
- end
-
- return HitRes
-end
-
-function ACF_PenetrateGround( Bullet, Energy, HitPos )
-
- local MaxDig = ((Energy.Penetration/Bullet["PenAera"])*ACF.KEtoRHA/ACF.GroundtoRHA)/25.4
- local CurDig = 0
- local DigStep = math.min(50,MaxDig)
-
- for i = 1,MaxDig/DigStep do
- --Msg("Step : ")
- --print(i)
- CurDig = DigStep*i
- local DigTr = { }
- DigTr.start = HitPos + (Bullet["Flight"]):GetNormalized()*CurDig
- DigTr.endpos = HitPos
- DigTr.filter = Bullet["Filter"]
- DigTr.mask = 16395
- local DigRes = util.TraceLine(DigTr) --Trace to see if it will hit anything
-
- if DigRes.Hit then
- if DigRes.Fraction > 0.01 and DigRes.Fraction < 0.99 then
- local Powerloss = (MaxDig - (CurDig - DigStep*DigRes.Fraction))/MaxDig
- --print(Powerloss)
- Bullet["Flight"] = Bullet["Flight"] * Powerloss
- --Msg("Penetrated the wall\n")
- Bullet["Pos"] = DigRes.HitPos
- return true
- else
- return nil
- end
- else
- --Msg("Didn't Hit\n")
- end
- end
-
- return nil
-
-end
-
-function ACF_KEShove(Target, Pos, Vec, KE )
-
- local phys = Target:GetPhysicsObject()
- if (Target:GetParent():IsValid()) then
- phys = Target:GetParent():GetPhysicsObject()
- end
- if (phys:IsValid()) then
- phys:ApplyForceOffset( Vec:GetNormal() * KE, Pos )
- end
-
-end
-
-function ACF_HEKill( Entity , HitVector , Energy )
-
- local obj = Entity:GetPhysicsObject()
- local grav = true
- local mass = nil
- if obj:IsValid() and ISSITP then
- grav = obj:IsGravityEnabled()
- mass = obj:GetMass()
- end
- constraint.RemoveAll( Entity )
- Entity:Remove()
-
- local Debris = ents.Create( "Debris" )
- Debris:SetModel( Entity:GetModel() )
- Debris:SetAngles( Entity:GetAngles() )
- Debris:SetPos( Entity:GetPos() )
- Debris:SetMaterial("models/props_wasteland/metal_tram001a")
- Debris:Spawn()
- Debris:Ignite(60,0)
- Debris:Activate()
-
- local phys = Debris:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:ApplyForceOffset( HitVector:GetNormal() * Energy * 350 , Debris:GetPos()+VectorRand()*20 )
- phys:EnableGravity( grav )
- if(mass != nil) then
- phys:SetMass(mass)
- end
- end
-
- return Debris
-
-end
-
-function ACF_APKill( Entity , HitVector , Power )
-
- constraint.RemoveAll( Entity )
- Entity:Remove()
-
- local Debris = ents.Create( "Debris" )
- Debris:SetModel( Entity:GetModel() )
- Debris:SetAngles( Entity:GetAngles() )
- Debris:SetPos( Entity:GetPos() )
- Debris:SetMaterial(Entity:GetMaterial())
- Debris:SetColor(Color(120,120,120,255))
- Debris:Spawn()
- Debris:Activate()
-
- local BreakEffect = EffectData()
- BreakEffect:SetOrigin( Entity:GetPos() )
- BreakEffect:SetScale( 20 )
- util.Effect( "WheelDust", BreakEffect )
-
- local phys = Debris:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:ApplyForceOffset( HitVector:GetNormal() * Power * 350 , Debris:GetPos()+VectorRand()*20 )
- end
-
- return Debris
-
-end
-
-function ACF_AmmoExplosion( Origin , Pos )
-
- local HEWeight = Origin.Ammo/2
- local LastHE = 0
- local Power = HEWeight * ACF.HEPower --Power in KiloJoules of the filler mass of TNT
- local Radius = (HEWeight)^0.33*8*39.37 --Scalling law found on the net, based on 1PSI overpressure from 1 kg of TNT at 15m
- local Search = true
- local Filter = {Origin}
-
- local Inflictor = nil
- if( Origin.Inflictor ) then
- Inflictor = Origin.Inflictor
- end
-
- Origin.IsExplosive = false
- Origin.Exploding = true
- Origin:Remove()
-
- while Search do
- for key,Found in pairs(ents.FindInSphere(Pos, Radius)) do
- if Found.IsExplosive and not Found.Exploding then
- local Hitat = Found:NearestPoint( Pos )
-
- local Occlusion = {}
- Occlusion.start = Pos
- Occlusion.endpos = Hitat
- Occlusion.filter = Filter
- local Occ = util.TraceLine( Occlusion )
-
- if ( Occ.Fraction == 0 ) then
- table.insert(Filter,Occ.Entity)
- local Occlusion = {}
- Occlusion.start = Pos
- Occlusion.endpos = Hitat
- Occlusion.filter = Filter
- Occ = util.TraceLine( Occlusion )
- --print("Ignoring nested prop")
- end
-
- if ( Occ.Hit and Occ.Entity:EntIndex() != Found.Entity:EntIndex() ) then
- --Msg("Target Occluded\n")
- else
- local FoundHE = Found.Ammo*2
- --Msg("Adding " ..FoundAmmo.. " to the blast\n")
- HEWeight = HEWeight + FoundHE
- --Msg("Boom = " ..BoomPower.. "\n")
- Found.IsExplosive = false
- Found.DamageAction = false
- Found.KillAction = false
- Found.Exploding = true
- table.insert(Filter,Found)
- Found:Remove()
-
- end
- end
- end
-
- if HEWeight > LastHE then
- Search = true
- LastHE = HEWeight
- Radius = (HEWeight)^0.33*8*39.37
- else
- Search = false
- end
-
- end
-
- ACF_HE( Pos , Vector(0,0,1) , HEWeight , HEWeight*0.5 , Inflictor , Origin )
-
- local Flash = EffectData()
- Flash:SetOrigin( Pos )
- Flash:SetNormal( Vector(0,0,-1) )
- Flash:SetRadius( math.max( Radius, 1 ) ) --Radius of the smoke
- util.Effect( "ACF_Scaled_Explosion", Flash )
-
-end
-
-function ACF_GetHitAngle( HitNormal , HitVector )
-
- HitVector = HitVector*-1
- local Angle = math.min(math.deg(math.acos(HitNormal:Dot( HitVector:GetNormal() ) ) ),89.999 )
- --Msg("Angle : " ..Angle.. "\n")
- return Angle
-
-end
diff --git a/lua/ACF/Shared/ACFGunList.lua b/lua/ACF/Shared/ACFGunList.lua
deleted file mode 100644
index 12a1e0ebe..000000000
--- a/lua/ACF/Shared/ACFGunList.lua
+++ /dev/null
@@ -1,1055 +0,0 @@
-AddCSLuaFile( "acf/shared/acfgunlist.lua" )
-
-
--- local Exemple = {} --That name is just a variable name and doesn't have much meaning
- -- Exemple.id = "7.62mmEx" --This is how we reference that gun everywhere
- -- Exemple.ent = "acf_gun" --This is the entity the menu has to spawn to use that gun
- -- Exemple.type = "Guns" --Another reference for the spawn menu
- -- Exemple.desc = "Exemple" --Spawn menu text
- -- Exemple.model = "models/error.mdl" --The model of that particular gun
- -- Exemple.caliber = 99 --The gun caliber in mm
- -- Exemple.gunclass = "MG" --A gun class code that determines a few attributes, the tables for that are lower in this file
- -- Exemple.weight = 99 --Weight, duh
- -- Exemple.round = {} --The table that defines that gun ammo
- -- Exemple.round.id = "7.62mmEX" --Ammo ID, if you actually want to fire it it has to be the same as the gun ID, first line in the table
- -- Exemple.round.emptyweight = 0.01 --Minimum ammo weight
- -- Exemple.round.maxweight = 0.05 --Max ammo weight
- -- Exemple.round.propweight = 0.010 --Max propellant weight
---Exemple["7.62mmEx"] = Exemple --Reference the gun table we defined into the gun listing
-
-
-local GunTable = {}
-
-local MG12mm = {}
- MG12mm.id = "12.7mmMG"
- MG12mm.ent = "acf_gun"
- MG12mm.type = "Guns"
- MG12mm.name = "12.7mm Machinegun"
- MG12mm.desc = "Machineguns are light guns that fire equally light bullets at a fast rate.\n The 12.7mm MG is the lightest one, firing relatively weak bullets, but still easilly capable of killing a man"
- MG12mm.model = "models/machinegun/machinegun_127mm.mdl"
- MG12mm.caliber = 1.27
- MG12mm.gunclass = "MG"
- MG12mm.weight = 30
- MG12mm.year = 1910
- MG12mm.round = {}
- MG12mm.round.id = "12.7mmMG"
- MG12mm.round.maxlength = 15.8
- MG12mm.round.propweight = 0.03
- if ( CLIENT ) then
- MG12mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- MG12mm.guiupdate = function() return end
- end
-GunTable["12.7mmMG"] = MG12mm
-
-local MG14mm = {}
- MG14mm.id = "14.5mmMG"
- MG14mm.ent = "acf_gun"
- MG14mm.type = "Guns"
- MG14mm.name = "14.5mm Machinegun"
- MG14mm.desc = "Machineguns are light guns that fire equally light bullets at a fast rate.\n The 14.5mm MG is the bigger, heavier cousin of the 12.7mm MG : able to fire heavier bullets at higher muzzle velocity, it suffers in size, weight and rate fo fire"
- MG14mm.model = "models/machinegun/machinegun_145mm.mdl"
- MG14mm.caliber = 1.45
- MG14mm.gunclass = "MG"
- MG14mm.weight = 45
- MG14mm.year = 1932
- MG14mm.round = {}
- MG14mm.round.id = "14.5mmMG"
- MG14mm.round.maxlength = 19.5
- MG14mm.round.propweight = 0.04
- if ( CLIENT ) then
- MG14mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- MG14mm.guiupdate = function() return end
- end
-GunTable["14.5mmMG"] = MG14mm
-
-local HMG20mm = {}
- HMG20mm.id = "20mmHMG"
- HMG20mm.ent = "acf_gun"
- HMG20mm.type = "Guns"
- HMG20mm.name = "20mm Heavy Machinegun"
- HMG20mm.desc = "The lightest of the HMGs, the 20mm fires a big round, but with poor accuracy and penetration"
- HMG20mm.model = "models/machinegun/machinegun_20mm_compact.mdl"
- HMG20mm.caliber = 2.0
- HMG20mm.gunclass = "HMG"
- HMG20mm.weight = 120
- HMG20mm.year = 1935
- HMG20mm.round = {}
- HMG20mm.round.id = "20mmHMG"
- HMG20mm.round.maxlength = 12.5
- HMG20mm.round.propweight = 0.05
- HMG20mm.magsize = 50
- HMG20mm.magreload = 3
- if ( CLIENT ) then
- HMG20mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- HMG20mm.guiupdate = function() return end
- end
-GunTable["20mmHMG"] = HMG20mm
-
-
- local HMG30mm = {}
- HMG30mm.id = "30mmHMG"
- HMG30mm.ent = "acf_gun"
- HMG30mm.type = "Guns"
- HMG30mm.name = "30mm Heavy Machinegun"
- HMG30mm.desc = "30mm shell chucker, light and compact, however suffers in accuracy and ballistics. Best used in aircraft"
- HMG30mm.model = "models/machinegun/machinegun_30mm_compact.mdl"
- HMG30mm.caliber = 3.0
- HMG30mm.gunclass = "HMG"
- HMG30mm.weight = 600
- HMG30mm.year = 1941
- HMG30mm.round = {}
- HMG30mm.round.id = "30mmHMG"
- HMG30mm.round.maxlength = 21.75
- HMG30mm.round.propweight = 0.13
- HMG30mm.magsize = 30
- HMG30mm.magreload = 3
- if ( CLIENT ) then
- HMG30mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- HMG30mm.guiupdate = function() return end
- end
-GunTable["30mmHMG"] = HMG30mm
-
-local HMG40mm = {}
- HMG40mm.id = "40mmHMG"
- HMG40mm.ent = "acf_gun"
- HMG40mm.type = "Guns"
- HMG40mm.name = "40mm Heavy Machinegun"
- HMG40mm.desc = "The heaviest of the heavy machineguns, this one boasts a useful payload, but suffers severely in ballistic performance"
- HMG40mm.model = "models/machinegun/machinegun_40mm_compact.mdl"
- HMG40mm.caliber = 4.0
- HMG40mm.gunclass = "HMG"
- HMG40mm.weight = 1250
- HMG40mm.year = 1935
- HMG40mm.round = {}
- HMG40mm.round.id = "40mmHMG"
- HMG40mm.round.maxlength = 28
- HMG40mm.round.propweight = 0.30
- HMG40mm.magsize = 20
- HMG40mm.magreload = 3
- if ( CLIENT ) then
- HMG40mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- HMG40mm.guiupdate = function() return end
- end
-GunTable["40mmHMG"] = HMG40mm
-
-local AC20mm = {}
- AC20mm.id = "20mmAC"
- AC20mm.ent = "acf_gun"
- AC20mm.type = "Guns"
- AC20mm.name = "20mm Autocannon"
- AC20mm.desc = "Autocannons have a rather high weight and bulk for the ammo they fire, but they can fire it extremely fast.\nThe 20mm AC is the smallest of the familly, boasting a good rate of fire but poor AP performance and insufficent space for a usefull shell payload"
- AC20mm.model = "models/autocannon/autocannon_20mm.mdl"
- AC20mm.caliber = 2.0
- AC20mm.gunclass = "AC"
- AC20mm.weight = 420
- AC20mm.year = 1930
- AC20mm.round = {}
- AC20mm.round.id = "20mmAC"
- AC20mm.round.maxlength = 28
- AC20mm.round.propweight = 0.12
- AC20mm.rofmod = 2
- AC20mm.magsize = 30
- AC20mm.magreload = 4
- if ( CLIENT ) then
- AC20mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AC20mm.guiupdate = function() return end
- end
-GunTable["20mmAC"] = AC20mm
-
-local AC30mm = {}
- AC30mm.id = "30mmAC"
- AC30mm.ent = "acf_gun"
- AC30mm.type = "Guns"
- AC30mm.name = "30mm Autocannon"
- AC30mm.desc = "Autocannons have a rather high weight and bulk for the ammo they fire, but they can fire it extremely fast.\nThe 30mm AC can fire shells with sufficient space for a usefull, if small payload"
- AC30mm.model = "models/autocannon/autocannon_30mm.mdl"
- AC30mm.caliber = 3.0
- AC30mm.gunclass = "AC"
- AC30mm.weight = 1230
- AC30mm.year = 1935
- AC30mm.round = {}
- AC30mm.round.id = "30mmAC"
- AC30mm.round.maxlength = 39
- AC30mm.round.propweight = 0.350
- AC30mm.rofmod = 1
- AC30mm.magsize = 20
- AC30mm.magreload = 3
- if ( CLIENT ) then
- AC30mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AC30mm.guiupdate = function() return end
- end
-GunTable["30mmAC"] = AC30mm
-
-local AC40mm = {}
- AC40mm.id = "40mmAC"
- AC40mm.ent = "acf_gun"
- AC40mm.type = "Guns"
- AC40mm.name = "40mm Autocannon"
- AC40mm.desc = "Autocannons have a rather high weight and bulk for the ammo they fire, but they can fire it extremely fast.\nThe 40mm AC can fire shells with sufficient space for a usefull payload, and can get decent penetration with proper rounds"
- AC40mm.model = "models/autocannon/autocannon_40mm.mdl"
- AC40mm.caliber = 4.0
- AC40mm.gunclass = "AC"
- AC40mm.weight = 1880
- AC40mm.year = 1940
- AC40mm.round = {}
- AC40mm.round.id = "40mmAC"
- AC40mm.round.maxlength = 45
- AC40mm.round.propweight = 0.9
- AC40mm.rofmod = 1
- AC40mm.magsize = 10
- AC40mm.magreload = 3
- if ( CLIENT ) then
- AC40mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AC40mm.guiupdate = function() return end
- end
-GunTable["40mmAC"] = AC40mm
-
-local AC50mm = {}
- AC50mm.id = "50mmAC"
- AC50mm.ent = "acf_gun"
- AC50mm.type = "Guns"
- AC50mm.name = "50mm Autocannon"
- AC50mm.desc = "Autocannons have a rather high weight and bulk for the ammo they fire, but they can fire it extremely fast.\nThe 50mm AC fires shells comparable with the 50mm Cannon, making it capable of defeating light armour handily"
- AC50mm.model = "models/autocannon/autocannon_50mm.mdl"
- AC50mm.caliber = 5.0
- AC50mm.gunclass = "AC"
- AC50mm.weight = 2450
- AC50mm.year = 1965
- AC50mm.round = {}
- AC50mm.round.id = "50mmAC"
- AC50mm.round.maxlength = 52
- AC50mm.round.propweight = 1.2
- AC50mm.rofmod = 1
- AC50mm.magsize = 5
- AC50mm.magreload = 3
- if ( CLIENT ) then
- AC50mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AC50mm.guiupdate = function() return end
- end
-GunTable["50mmAC"] = AC50mm
-
-local RAC20mm = {}
- RAC20mm.id = "20mmRAC"
- RAC20mm.ent = "acf_gun"
- RAC20mm.type = "Guns"
- RAC20mm.name = "20mm Rotary Autocannon"
- RAC20mm.desc = "Rotary Autocannons sacrifice weight, bulk and accuracy over classic Autocannons to get the highest rate of fire possible"
- RAC20mm.model = "models/rotarycannon/rotarycannon_20mm.mdl"
- RAC20mm.caliber = 2.0
- RAC20mm.gunclass = "RAC"
- RAC20mm.weight = 1260
- RAC20mm.year = 1965
- RAC20mm.round = {}
- RAC20mm.round.id = "20mmRAC"
- RAC20mm.round.maxlength = 28
- RAC20mm.round.propweight = 0.12
- RAC20mm.magsize = 50
- RAC20mm.magreload = 8
- if ( CLIENT ) then
- RAC20mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- RAC20mm.guiupdate = function() return end
- end
-GunTable["20mmRAC"] = RAC20mm
-
-local RAC30mm = {}
- RAC30mm.id = "30mmRAC"
- RAC30mm.ent = "acf_gun"
- RAC30mm.type = "Guns"
- RAC30mm.name = "30mm Rotary Autocannon"
- RAC30mm.desc = "Rotary Autocannons sacrifice weight, bulk and accuracy over classic Autocannons to get the highest rate of fire possible"
- RAC30mm.model = "models/rotarycannon/rotarycannon_30mm.mdl"
- RAC30mm.caliber = 3.0
- RAC30mm.gunclass = "RAC"
- RAC30mm.weight = 3680
- RAC30mm.year = 1975
- RAC30mm.round = {}
- RAC30mm.round.id = "30mmRAC"
- RAC30mm.round.maxlength = 39
- RAC30mm.round.propweight = 0.350
- RAC30mm.magsize = 50
- RAC30mm.magreload = 12
- if ( CLIENT ) then
- RAC30mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- RAC30mm.guiupdate = function() return end
- end
-GunTable["30mmRAC"] = RAC30mm
---Autoloaders
-
-local AL100mm = {}
- AL100mm.id = "100mmAL"
- AL100mm.ent = "acf_gun"
- AL100mm.type = "Guns"
- AL100mm.name = "100mm Autoloading Cannon"
- AL100mm.desc = "Fast firing, high velocity gun, however bulky and heavy"
- AL100mm.model = "models/tankgun/tankgun_al_100mm.mdl"
- AL100mm.caliber = 10.0
- AL100mm.gunclass = "AL"
- AL100mm.weight = 3750
- AL100mm.year = 1956
- -- new stuff
- AL100mm.rofmod = 0.8
- AL100mm.magsize = 6
- AL100mm.magreload = 20
- --
- AL100mm.round = {}
- AL100mm.round.id = "100mmAL"
- AL100mm.round.maxlength = 80
- AL100mm.round.propweight = 7
- if ( CLIENT ) then
- AL100mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AL100mm.guiupdate = function() return end
- end
-GunTable["100mmAL"] = AL100mm
-
-local AL120mm = {}
- AL120mm.id = "120mmAL"
- AL120mm.ent = "acf_gun"
- AL120mm.type = "Guns"
- AL120mm.name = "120mm Autoloading Cannon"
- AL120mm.desc = "Fast firing, high velocity gun, however bulky and heavy"
- AL120mm.model = "models/tankgun/tankgun_al_120mm.mdl"
- AL120mm.caliber = 12.0
- AL120mm.gunclass = "AL"
- AL120mm.weight = 6200
- AL120mm.year = 1956
- -- new stuff
- AL120mm.rofmod = 0.8
- AL120mm.magsize = 4
- AL120mm.magreload = 30
- --
- AL120mm.round = {}
- AL120mm.round.id = "120mmAL"
- AL120mm.round.maxlength = 102
- AL120mm.round.propweight = 13
- if ( CLIENT ) then
- AL120mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AL120mm.guiupdate = function() return end
- end
-GunTable["120mmAL"] = AL120mm
-
-local AL140mm = {}
- AL140mm.id = "140mmAL"
- AL140mm.ent = "acf_gun"
- AL140mm.type = "Guns"
- AL140mm.name = "140mm Autoloading Cannon"
- AL140mm.desc = "Fast firing, high velocity gun, however bulky and heavy"
- AL140mm.model = "models/tankgun/tankgun_al_140mm.mdl"
- AL140mm.caliber = 14.0
- AL140mm.gunclass = "AL"
- AL140mm.weight = 9180
- AL140mm.year = 1970
- -- new stuff
- AL140mm.rofmod = 0.8
- AL140mm.magsize = 4
- AL140mm.magreload = 45
- --
- AL140mm.round = {}
- AL140mm.round.id = "140mmAL"
- AL140mm.round.maxlength = 122
- AL140mm.round.propweight = 23
- if ( CLIENT ) then
- AL140mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AL140mm.guiupdate = function() return end
- end
-GunTable["140mmAL"] = AL140mm
-
-local AL75mm = {}
- AL75mm.id = "75mmAL"
- AL75mm.ent = "acf_gun"
- AL75mm.type = "Guns"
- AL75mm.name = "75mm Autoloading Cannon"
- AL75mm.desc = "Fast firing, high velocity gun, however bulky and heavy"
- AL75mm.model = "models/tankgun/tankgun_al_75mm.mdl"
- AL75mm.caliber = 7.5
- AL75mm.gunclass = "AL"
- AL75mm.weight = 2420
- AL75mm.year = 1946
- -- new stuff
- AL75mm.rofmod = 0.8
- AL75mm.magsize = 6
- AL75mm.magreload = 15
- --
- AL75mm.round = {}
- AL75mm.round.id = "75mmAL"
- AL75mm.round.maxlength = 70
- AL75mm.round.propweight = 4
- if ( CLIENT ) then
- AL75mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AL75mm.guiupdate = function() return end
- end
-GunTable["75mmAL"] = AL75mm
-
- local AL50mm = {}
- AL50mm.id = "50mmAL"
- AL50mm.ent = "acf_gun"
- AL50mm.type = "Guns"
- AL50mm.name = "50mm Autoloading Cannon"
- AL50mm.desc = "Fast firing, high velocity gun, however bulky and heavy"
- AL50mm.model = "models/tankgun/tankgun_al_50mm.mdl"
- AL50mm.caliber = 5.0
- AL50mm.gunclass = "AL"
- AL50mm.weight = 1665
- AL50mm.year = 1966
- -- new stuff
- AL50mm.rofmod = 0.8
- AL50mm.magsize = 8
- AL50mm.magreload = 10
- --
- AL50mm.round = {}
- AL50mm.round.id = "50mmAL"
- AL50mm.round.maxlength = 55
- AL50mm.round.propweight = 1.3
- if ( CLIENT ) then
- AL50mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- AL50mm.guiupdate = function() return end
- end
-GunTable["50mmAL"] = AL50mm
-
-
-local Gun50mm = {}
- Gun50mm.id = "50mmC"
- Gun50mm.ent = "acf_gun"
- Gun50mm.type = "Guns"
- Gun50mm.name = "50mm Tank Gun"
- Gun50mm.desc = "High velocity guns that can fire very powerful ammunition, but are rather slow to reload"
- Gun50mm.model = "models/tankgun/tankgun_50mm.mdl"
- Gun50mm.caliber = 5.0
- Gun50mm.gunclass = "C"
- Gun50mm.weight = 665
- Gun50mm.year = 1935
- Gun50mm.sound = "weapons/ACF_Gun/ac_fire4.wav"
- Gun50mm.round = {}
- Gun50mm.round.id = "50mmC"
- Gun50mm.round.maxlength = 55
- Gun50mm.round.propweight = 1.3
- if ( CLIENT ) then
- Gun50mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- Gun50mm.guiupdate = function() return end
- end
-GunTable["50mmC"] = Gun50mm
-
-local Gun75mm = {}
- Gun75mm.id = "75mmC"
- Gun75mm.ent = "acf_gun"
- Gun75mm.type = "Guns"
- Gun75mm.name = "75mm Tank Gun"
- Gun75mm.desc = "High velocity guns that can fire very powerful ammunition, but are rather slow to reload"
- Gun75mm.model = "models/tankgun/tankgun_75mm.mdl"
- Gun75mm.caliber = 7.5
- Gun75mm.gunclass = "C"
- Gun75mm.weight = 1420
- Gun75mm.year = 1942
- Gun75mm.round = {}
- Gun75mm.round.id = "75mmC"
- Gun75mm.round.maxlength = 70
- Gun75mm.round.propweight = 4
- if ( CLIENT ) then
- Gun75mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- Gun75mm.guiupdate = function() return end
- end
-GunTable["75mmC"] = Gun75mm
-
-local Gun100mm = {}
- Gun100mm.id = "100mmC"
- Gun100mm.ent = "acf_gun"
- Gun100mm.type = "Guns"
- Gun100mm.name = "100mm Tank Gun"
- Gun100mm.desc = "High velocity guns that can fire very powerful ammunition, but are rather slow to reload"
- Gun100mm.model = "models/tankgun/tankgun_100mm.mdl"
- Gun100mm.caliber = 10.0
- Gun100mm.gunclass = "C"
- Gun100mm.weight = 2750
- Gun100mm.year = 1944
- Gun100mm.round = {}
- Gun100mm.round.id = "100mmC"
- Gun100mm.round.maxlength = 80
- Gun100mm.round.propweight = 7
- if ( CLIENT ) then
- Gun100mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- Gun100mm.guiupdate = function() return end
- end
-GunTable["100mmC"] = Gun100mm
-
-local Gun120mm = {}
- Gun120mm.id = "120mmC"
- Gun120mm.ent = "acf_gun"
- Gun120mm.type = "Guns"
- Gun120mm.name = "120mm Tank Gun"
- Gun120mm.desc = "High velocity guns that can fire very powerful ammunition, but are rather slow to reload"
- Gun120mm.model = "models/tankgun/tankgun_120mm.mdl"
- Gun120mm.caliber = 12.0
- Gun120mm.gunclass = "C"
- Gun120mm.weight = 5200
- Gun120mm.year = 1955
- Gun120mm.round = {}
- Gun120mm.round.id = "120mmC"
- Gun120mm.round.maxlength = 102
- Gun120mm.round.propweight = 13
- if ( CLIENT ) then
- Gun120mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- Gun120mm.guiupdate = function() return end
- end
-GunTable["120mmC"] = Gun120mm
-
-local Gun140mm = {}
- Gun140mm.id = "140mmC"
- Gun140mm.ent = "acf_gun"
- Gun140mm.type = "Guns"
- Gun140mm.name = "140mm Tank Gun"
- Gun140mm.desc = "High velocity guns that can fire very powerful ammunition, but are rather slow to reload"
- Gun140mm.model = "models/tankgun/tankgun_140mm.mdl"
- Gun140mm.caliber = 14.0
- Gun140mm.gunclass = "C"
- Gun140mm.weight = 8180
- Gun140mm.year = 1990
- Gun140mm.round = {}
- Gun140mm.round.id = "140mmC"
- Gun140mm.round.maxlength = 122
- Gun140mm.round.propweight = 23
- if ( CLIENT ) then
- Gun140mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- Gun140mm.guiupdate = function() return end
- end
-GunTable["140mmC"] = Gun140mm
-
-local How75mm = {}
- How75mm.id = "75mmHW"
- How75mm.ent = "acf_gun"
- How75mm.type = "Guns"
- How75mm.name = "75mm Howitzer"
- How75mm.desc = "Howitzers are limited to rather mediocre muzzle velocities, but can fire extremely heavy projectiles with large usefull payload capacities."
- How75mm.model = "models/howitzer/howitzer_75mm.mdl"
- How75mm.caliber = 7.5
- How75mm.gunclass = "HW"
- How75mm.weight = 530
- How75mm.year = 1900
- How75mm.round = {}
- How75mm.round.id = "75mmHW"
- How75mm.round.maxlength = 60
- How75mm.round.propweight = 1.8
- if ( CLIENT ) then
- How75mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- How75mm.guiupdate = function() return end
- end
-GunTable["75mmHW"] = How75mm
-
-local How105mm = {}
- How105mm.id = "105mmHW"
- How105mm.ent = "acf_gun"
- How105mm.type = "Guns"
- How105mm.name = "105mm Howitzer"
- How105mm.desc = "Howitzers are limited to rather mediocre muzzle velocities, but can fire extremely heavy projectiles with large usefull payload capacities."
- How105mm.model = "models/howitzer/howitzer_105mm.mdl"
- How105mm.caliber = 10.5
- How105mm.gunclass = "HW"
- How105mm.weight = 1810
- How105mm.year = 1900
- How105mm.round = {}
- How105mm.round.id = "105mmHW"
- How105mm.round.maxlength = 84
- How105mm.round.propweight = 2.9
- if ( CLIENT ) then
- How105mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- How105mm.guiupdate = function() return end
- end
-GunTable["105mmHW"] = How105mm
-
-local How155mm = {}
- How155mm.id = "155mmHW"
- How155mm.ent = "acf_gun"
- How155mm.type = "Guns"
- How155mm.name = "155mm Howitzer"
- How155mm.desc = "Howitzers are limited to rather mediocre muzzle velocities, but can fire extremely heavy projectiles with large usefull payload capacities."
- How155mm.model = "models/howitzer/howitzer_155mm.mdl"
- How155mm.caliber = 15.5
- How155mm.gunclass = "HW"
- How155mm.weight = 5340
- How155mm.year = 1900
- How155mm.round = {}
- How155mm.round.id = "155mmHW"
- How155mm.round.maxlength = 124
- How155mm.round.propweight = 13.5
- if ( CLIENT ) then
- How155mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- How155mm.guiupdate = function() return end
- end
-GunTable["155mmHW"] = How155mm
-
-local How203mm = {}
- How203mm.id = "203mmHW"
- How203mm.ent = "acf_gun"
- How203mm.type = "Guns"
- How203mm.name = "203mm Howitzer"
- How203mm.desc = "Howitzers are limited to rather mediocre muzzle velocities, but can fire extremely heavy projectiles with large usefull payload capacities."
- How203mm.model = "models/howitzer/howitzer_203mm.mdl"
- How203mm.caliber = 20.3
- How203mm.gunclass = "HW"
- How203mm.weight = 10280
- How203mm.year = 1900
- How203mm.round = {}
- How203mm.round.id = "203mmHW"
- How203mm.round.maxlength = 162.4
- How203mm.round.propweight = 28.5
- if ( CLIENT ) then
- How203mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- How203mm.guiupdate = function() return end
- end
-GunTable["203mmHW"] = How203mm
-
-local GL40mm = {}
- GL40mm.id = "40mmGL"
- GL40mm.ent = "acf_gun"
- GL40mm.type = "Guns"
- GL40mm.name = "40mm Grenade Machine Gun"
- GL40mm.desc = "Grenade Launchers can fire shells with relatively large payloads at a fast rate, but with very limited velocities and bad accuracy"
- GL40mm.model = "models/launcher/40mmgl.mdl"
- GL40mm.caliber = 4.0
- GL40mm.gunclass = "GL"
- GL40mm.weight = 55
- GL40mm.year = 1970
- GL40mm.round = {}
- GL40mm.round.id = "40mmGL"
- GL40mm.round.maxlength = 7.5
- GL40mm.round.propweight = 0.01
- if ( CLIENT ) then
- GL40mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- GL40mm.guiupdate = function() return end
- end
-GunTable["40mmGL"] = GL40mm
-
-local MO80mm = {}
- MO80mm.id = "80mmM"
- MO80mm.ent = "acf_gun"
- MO80mm.type = "Guns"
- MO80mm.name = "80mm Mortar"
- MO80mm.desc = "Mortars are able to fire shells with extremely high usefull payloads from a light weight gun, at the price of a low rate of fire and extremely limited velocities"
- MO80mm.model = "models/mortar/mortar_80mm.mdl"
- MO80mm.caliber = 8.0
- MO80mm.gunclass = "MO"
- MO80mm.weight = 120
- MO80mm.year = 1930
- MO80mm.round = {}
- MO80mm.round.id = "80mmM"
- MO80mm.round.maxlength = 28
- MO80mm.round.propweight = 0.055
- if ( CLIENT ) then
- MO80mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- MO80mm.guiupdate = function() return end
- end
-GunTable["80mmM"] = MO80mm
-
-local MO120mm = {}
- MO120mm.id = "120mmM"
- MO120mm.ent = "acf_gun"
- MO120mm.type = "Guns"
- MO120mm.name = "120mm Mortar"
- MO120mm.desc = "Mortars are able to fire shells with extremely high usefull payloads from a light weight gun, at the price of a low rate of fire and extremely limited velocities"
- MO120mm.model = "models/mortar/mortar_120mm.mdl"
- MO120mm.caliber = 12.0
- MO120mm.gunclass = "MO"
- MO120mm.weight = 640
- MO120mm.year = 1935
- MO120mm.round = {}
- MO120mm.round.id = "120mmM"
- MO120mm.round.maxlength = 45
- MO120mm.round.propweight = 0.175
- if ( CLIENT ) then
- MO120mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- MO120mm.guiupdate = function() return end
- end
-GunTable["120mmM"] = MO120mm
-
-local MO200mm = {}
- MO200mm.id = "200mmM"
- MO200mm.ent = "acf_gun"
- MO200mm.type = "Guns"
- MO200mm.name = "200mm Mortar"
- MO200mm.desc = "Mortars are able to fire shells with extremely high usefull payloads from a light weight gun, at the price of a low rate of fire and extremely limited velocities"
- MO200mm.model = "models/mortar/mortar_200mm.mdl"
- MO200mm.caliber = 20.0
- MO200mm.gunclass = "MO"
- MO200mm.weight = 2850
- MO200mm.year = 1940
- MO200mm.round = {}
- MO200mm.round.id = "200mmM"
- MO200mm.round.maxlength = 80
- MO200mm.round.propweight = 0.330
- if ( CLIENT ) then
- MO200mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- MO200mm.guiupdate = function() return end
- end
-GunTable["200mmM"] = MO200mm
-
-local SL40mm = {}
- SL40mm.id = "40mmSL"
- SL40mm.ent = "acf_gun"
- SL40mm.type = "Guns"
- SL40mm.name = "40mm Smoke Launcher"
- SL40mm.desc = "Smoke launcher to block an attacker's line of sight"
- SL40mm.model = "models/launcher/40mmgl.mdl"
- SL40mm.caliber = 4.0
- SL40mm.gunclass = "SL"
- SL40mm.weight = 55
- SL40mm.year = 1941
- SL40mm.round = {}
- SL40mm.round.id = "40mmSL"
- SL40mm.round.maxlength = 15
- SL40mm.round.propweight = 0.00005
-
-
- if ( CLIENT ) then
- SL40mm.guicreate = (function( Panel, Table ) ACFGunGUICreate( Table ) end or nil)
- SL40mm.guiupdate = function() return end
- end
-GunTable["40mmSL"] = SL40mm
-
-list.Set( "ACFEnts", "Guns", GunTable )
-
-local GunClass = {} --Start gun classes listing
---sound is used for the loudass sounds, soundDistance uses a script for a distance shot, soundNormal is for machineguns so they're not superloud
-local Machinegun = {}
- Machinegun.spread = 1
- Machinegun.name = "Machinegun"
- Machinegun.muzzleflash = "50cal_muzzleflash_noscale"
- Machinegun.rofmod = 0.9
- Machinegun.soundNormal = "weapons/ACF_Gun/mg_fire4.wav"
- Machinegun.sound = " "
- Machinegun.soundDistance = " "
-GunClass["MG"] = Machinegun
-
-local Autocannon = {}
- Autocannon.spread = 1
- Autocannon.name = "Autocannon"
- Autocannon.muzzleflash = "30mm_muzzleflash_noscale"
- Autocannon.rofmod = 0.35
- Autocannon.sound = "weapons/ACF_Gun/ac_fire4.wav"
- Autocannon.soundDistance = " "
- Autocannon.soundNormal = " "
-
-GunClass["AC"] = Autocannon
-
-local HeavyMachinegun = {}
- HeavyMachinegun.spread = 2
- HeavyMachinegun.name = "Heavy Machinegun"
- HeavyMachinegun.muzzleflash = "50cal_muzzleflash_noscale"
- HeavyMachinegun.rofmod = 0.30
- HeavyMachinegun.sound = "weapons/ACF_Gun/mg_fire3.wav"
- HeavyMachinegun.soundDistance = " "
- HeavyMachinegun.soundNormal = " "
-GunClass["HMG"] = HeavyMachinegun
-
-local Gatling = {}
- Gatling.spread = 3
- Gatling.name = "Rotary Autocannon"
- Gatling.muzzleflash = "50cal_muzzleflash_noscale"
- Gatling.rofmod = 0.07
- Gatling.sound = "weapons/ACF_Gun/rac_fire1.wav"
- Gatling.soundDistance = " "
- Gatling.soundNormal = " "
-GunClass["RAC"] = Gatling
-
-local Cannon = {}
- Cannon.spread = 0.7
- Cannon.name = "Cannon"
- Cannon.muzzleflash = "120mm_muzzleflash_noscale"
- Cannon.rofmod = 1.5
- Cannon.sound = "weapons/ACF_Gun/cannon_new.wav"
- Cannon.soundDistance = "Cannon.Fire"
- Cannon.soundNormal = " "
-GunClass["C"] = Cannon
-
-local Autoloader= {}
- Autoloader.spread = 0.7
- Autoloader.name = "Autoloader"
- Autoloader.muzzleflash = "120mm_muzzleflash_noscale"
- Autoloader.rofmod = 0.8
- Autoloader.sound = "weapons/ACF_Gun/autoloader.wav"
- Autoloader.soundDistance = "Cannon.Fire"
- Autoloader.soundNormal = " "
-GunClass["AL"] = Autoloader
-
-local Howitzer = {}
- Howitzer.spread = 0.5
- Howitzer.name = "Howitzer"
- Howitzer.muzzleflash = "120mm_muzzleflash_noscale"
- Howitzer.rofmod = 1.3
- Howitzer.sound = "weapons/ACF_Gun/howitzer_new2.wav"
- Howitzer.soundDistance = "Howitzer.Fire"
- Howitzer.soundNormal = " "
-GunClass["HW"] = Howitzer
-
-local Mortar = {}
- Mortar.spread = 4
- Mortar.name = "Mortar"
- Mortar.muzzleflash = "40mm_muzzleflash_noscale"
- Mortar.rofmod = 3
- Mortar.sound = "weapons/ACF_Gun/mortar_new.wav"
- Mortar.soundDistance = "Mortar.Fire"
- Mortar.soundNormal = " "
-GunClass["MO"] = Mortar
-
-local GLauncher = {}
- GLauncher.spread = 2
- GLauncher.name = "Grenade Launcher"
- GLauncher.muzzleflash = "40mm_muzzleflash_noscale"
- GLauncher.rofmod = 1
- GLauncher.sound = "weapons/grenade_launcher1.wav"
- GLauncher.soundDistance = " "
- GLauncher.soundNormal = " "
-GunClass["GL"] = GLauncher
-
-local SmokeLauncher = {}
- SmokeLauncher.spread = 2
- SmokeLauncher.name = "Smoke Launcher"
- SmokeLauncher.muzzleflash = "40mm_muzzleflash_noscale"
- SmokeLauncher.rofmod = 60 --60
- SmokeLauncher.sound = "weapons/ACF_Gun/mortar_new.wav"
- SmokeLauncher.soundDistance = "Mortar.Fire"
- SmokeLauncher.soundNormal = " "
-GunClass["SL"] = SmokeLauncher
-
-list.Set( "ACFClasses", "GunClass", GunClass ) --End gun classes listing
-
-local AmmoTable = {} --Start ammo containers listing
-
-local AmmoSmall = {}
- AmmoSmall.id = "AmmoSmall"
- AmmoSmall.ent = "acf_ammo"
- AmmoSmall.type = "Ammo"
- AmmoSmall.name = "Small Ammo Crate"
- AmmoSmall.desc = "Small ammo crate\n"
- AmmoSmall.model = "models/ammocrate_small.mdl"
- AmmoSmall.weight = 7
-AmmoTable["AmmoSmall"] = AmmoSmall
-
-local AmmoMedCube = {}
- AmmoMedCube.id = "AmmoMedCube"
- AmmoMedCube.ent = "acf_ammo"
- AmmoMedCube.type = "Ammo"
- AmmoMedCube.name = "Medium cubic ammo crate"
- AmmoMedCube.desc = "Medium cubic ammo crate\n"
- AmmoMedCube.model = "models/ammocrate_medium_small.mdl"
- AmmoMedCube.weight = 80
-AmmoTable["AmmoMedCube"] = AmmoMedCube
-
-local AmmoMedium = {}
- AmmoMedium.id = "AmmoMedium"
- AmmoMedium.ent = "acf_ammo"
- AmmoMedium.type = "Ammo"
- AmmoMedium.name = "Medium Ammo Crate"
- AmmoMedium.desc = "Medium ammo crate\n"
- AmmoMedium.model = "models/ammocrate_medium.mdl"
- AmmoMedium.weight = 150
-AmmoTable["AmmoMedium"] = AmmoMedium
-
-local AmmoLarge = {}
- AmmoLarge.id = "AmmoLarge"
- AmmoLarge.ent = "acf_ammo"
- AmmoLarge.type = "Ammo"
- AmmoLarge.name = "Large Ammo Crate"
- AmmoLarge.desc = "Large ammo crate\n"
- AmmoLarge.model = "models/ammocrate_large.mdl"
- AmmoLarge.weight = 1000
-AmmoTable["AmmoLarge"] = AmmoLarge
-
-local Ammo2x2x1 = {}
- Ammo2x2x1.id = "Ammo2x2x1"
- Ammo2x2x1.ent = "acf_ammo"
- Ammo2x2x1.type = "Ammo"
- Ammo2x2x1.name = "Modular Ammo Crate"
- Ammo2x2x1.desc = "Modular Ammo Crate 2x2x1 Size\n"
- Ammo2x2x1.model = "models/ammocrates/ammocrate_2x2x1.mdl"
- Ammo2x2x1.weight = 20
-AmmoTable["Ammo2x2x1"] = Ammo2x2x1
-
-local Ammo2x2x2 = {}
- Ammo2x2x2.id = "Ammo2x2x2"
- Ammo2x2x2.ent = "acf_ammo"
- Ammo2x2x2.type = "Ammo"
- Ammo2x2x2.name = "Modular Ammo Crate"
- Ammo2x2x2.desc = "Modular Ammo Crate 2x2x2 Size\n"
- Ammo2x2x2.model = "models/ammocrates/ammocrate_2x2x2.mdl"
- Ammo2x2x2.weight = 40
-AmmoTable["Ammo2x2x2"] = Ammo2x2x2
-
-local Ammo2x2x4 = {}
- Ammo2x2x4.id = "Ammo2x2x4"
- Ammo2x2x4.ent = "acf_ammo"
- Ammo2x2x4.type = "Ammo"
- Ammo2x2x4.name = "Modular Ammo Crate"
- Ammo2x2x4.desc = "Modular Ammo Crate 2x2x4 Size\n"
- Ammo2x2x4.model = "models/ammocrates/ammocrate_2x2x4.mdl"
- Ammo2x2x4.weight = 80
-AmmoTable["Ammo2x2x4"] = Ammo2x2x4
-
-local Ammo2x3x1 = {}
- Ammo2x3x1.id = "Ammo2x3x1"
- Ammo2x3x1.ent = "acf_ammo"
- Ammo2x3x1.type = "Ammo"
- Ammo2x3x1.name = "Modular Ammo Crate"
- Ammo2x3x1.desc = "Modular Ammo Crate 2x3x1 Size\n"
- Ammo2x3x1.model = "models/ammocrates/ammocrate_2x3x1.mdl"
- Ammo2x3x1.weight = 30
-AmmoTable["Ammo2x3x1"] = Ammo2x3x1
-
-local Ammo2x3x2 = {}
- Ammo2x3x2.id = "Ammo2x3x2"
- Ammo2x3x2.ent = "acf_ammo"
- Ammo2x3x2.type = "Ammo"
- Ammo2x3x2.name = "Modular Ammo Crate"
- Ammo2x3x2.desc = "Modular Ammo Crate 2x3x2 Size\n"
- Ammo2x3x2.model = "models/ammocrates/ammocrate_2x3x2.mdl"
- Ammo2x3x2.weight = 60
-AmmoTable["Ammo2x3x2"] = Ammo2x3x2
-
-local Ammo2x3x4 = {}
- Ammo2x3x4.id = "Ammo2x3x4"
- Ammo2x3x4.ent = "acf_ammo"
- Ammo2x3x4.type = "Ammo"
- Ammo2x3x4.name = "Modular Ammo Crate"
- Ammo2x3x4.desc = "Modular Ammo Crate 2x3x4 Size\n"
- Ammo2x3x4.model = "models/ammocrates/ammocrate_2x3x4.mdl"
- Ammo2x3x4.weight = 120
-AmmoTable["Ammo2x3x4"] = Ammo2x3x4
-
-local Ammo2x4x1 = {}
- Ammo2x4x1.id = "Ammo2x4x1"
- Ammo2x4x1.ent = "acf_ammo"
- Ammo2x4x1.type = "Ammo"
- Ammo2x4x1.name = "Modular Ammo Crate"
- Ammo2x4x1.desc = "Modular Ammo Crate 2x4x1 Size\n"
- Ammo2x4x1.model = "models/ammocrates/ammocrate_2x4x1.mdl"
- Ammo2x4x1.weight = 40
-AmmoTable["Ammo2x4x1"] = Ammo2x4x1
-
-local Ammo2x4x2 = {}
- Ammo2x4x2.id = "Ammo2x4x2"
- Ammo2x4x2.ent = "acf_ammo"
- Ammo2x4x2.type = "Ammo"
- Ammo2x4x2.name = "Modular Ammo Crate"
- Ammo2x4x2.desc = "Modular Ammo Crate 2x4x2 Size\n"
- Ammo2x4x2.model = "models/ammocrates/ammocrate_2x4x2.mdl"
- Ammo2x4x2.weight = 80
-AmmoTable["Ammo2x4x2"] = Ammo2x4x2
-
-local Ammo2x4x4 = {}
- Ammo2x4x4.id = "Ammo2x4x4"
- Ammo2x4x4.ent = "acf_ammo"
- Ammo2x4x4.type = "Ammo"
- Ammo2x4x4.name = "Modular Ammo Crate"
- Ammo2x4x4.desc = "Modular Ammo Crate 2x4x4 Size\n"
- Ammo2x4x4.model = "models/ammocrates/ammocrate_2x4x4.mdl"
- Ammo2x4x4.weight = 160
-AmmoTable["Ammo2x4x4"] = Ammo2x4x4
-
-local Ammo2x4x6 = {}
- Ammo2x4x6.id = "Ammo2x4x6"
- Ammo2x4x6.ent = "acf_ammo"
- Ammo2x4x6.type = "Ammo"
- Ammo2x4x6.name = "Modular Ammo Crate"
- Ammo2x4x6.desc = "Modular Ammo Crate 2x4x6 Size\n"
- Ammo2x4x6.model = "models/ammocrates/ammocrate_2x4x6.mdl"
- Ammo2x4x6.weight = 240
-AmmoTable["Ammo2x4x6"] = Ammo2x4x6
-
-local Ammo2x4x8 = {}
- Ammo2x4x8.id = "Ammo2x4x8"
- Ammo2x4x8.ent = "acf_ammo"
- Ammo2x4x8.type = "Ammo"
- Ammo2x4x8.name = "Modular Ammo Crate"
- Ammo2x4x8.desc = "Modular Ammo Crate 2x4x8 Size\n"
- Ammo2x4x8.model = "models/ammocrates/ammocrate_2x4x8.mdl"
- Ammo2x4x8.weight = 320
-AmmoTable["Ammo2x4x8"] = Ammo2x4x8
-
-local Ammo3x4x1 = {}
- Ammo3x4x1.id = "Ammo3x4x1"
- Ammo3x4x1.ent = "acf_ammo"
- Ammo3x4x1.type = "Ammo"
- Ammo3x4x1.name = "Modular Ammo Crate"
- Ammo3x4x1.desc = "Modular Ammo Crate 3x4x1 Size\n"
- Ammo3x4x1.model = "models/ammocrates/ammocrate_3x4x1.mdl"
- Ammo3x4x1.weight = 60
-AmmoTable["Ammo3x4x1"] = Ammo3x4x1
-
-local Ammo3x4x2 = {}
- Ammo3x4x2.id = "Ammo3x4x2"
- Ammo3x4x2.ent = "acf_ammo"
- Ammo3x4x2.type = "Ammo"
- Ammo3x4x2.name = "Modular Ammo Crate"
- Ammo3x4x2.desc = "Modular Ammo Crate 3x4x2 Size\n"
- Ammo3x4x2.model = "models/ammocrates/ammocrate_3x4x2.mdl"
- Ammo3x4x2.weight = 120
-AmmoTable["Ammo3x4x2"] = Ammo3x4x2
-
-local Ammo3x4x4 = {}
- Ammo3x4x4.id = "Ammo3x4x4"
- Ammo3x4x4.ent = "acf_ammo"
- Ammo3x4x4.type = "Ammo"
- Ammo3x4x4.name = "Modular Ammo Crate"
- Ammo3x4x4.desc = "Modular Ammo Crate 3x4x4 Size\n"
- Ammo3x4x4.model = "models/ammocrates/ammocrate_3x4x4.mdl"
- Ammo3x4x4.weight = 240
-AmmoTable["Ammo3x4x4"] = Ammo3x4x4
-
-local Ammo3x4x6 = {}
- Ammo3x4x6.id = "Ammo3x4x6"
- Ammo3x4x6.ent = "acf_ammo"
- Ammo3x4x6.type = "Ammo"
- Ammo3x4x6.name = "Modular Ammo Crate"
- Ammo3x4x6.desc = "Modular Ammo Crate 3x4x6 Size\n"
- Ammo3x4x6.model = "models/ammocrates/ammocrate_3x4x6.mdl"
- Ammo3x4x6.weight = 360
-AmmoTable["Ammo3x4x6"] = Ammo3x4x6
-
-local Ammo3x4x8 = {}
- Ammo3x4x8.id = "Ammo3x4x8"
- Ammo3x4x8.ent = "acf_ammo"
- Ammo3x4x8.type = "Ammo"
- Ammo3x4x8.name = "Modular Ammo Crate"
- Ammo3x4x8.desc = "Modular Ammo Crate 3x4x8 Size\n"
- Ammo3x4x8.model = "models/ammocrates/ammocrate_3x4x8.mdl"
- Ammo3x4x8.weight = 480
-AmmoTable["Ammo3x4x8"] = Ammo3x4x8
-
-local Ammo4x4x2 = {}
- Ammo4x4x2.id = "Ammo4x4x2"
- Ammo4x4x2.ent = "acf_ammo"
- Ammo4x4x2.type = "Ammo"
- Ammo4x4x2.name = "Modular Ammo Crate"
- Ammo4x4x2.desc = "Modular Ammo Crate 4x4x2 Size\n"
- Ammo4x4x2.model = "models/ammocrates/ammocrate_4x4x2.mdl"
- Ammo4x4x2.weight = 160
-AmmoTable["Ammo4x4x2"] = Ammo4x4x2
-
-local Ammo4x4x4 = {}
- Ammo4x4x4.id = "Ammo4x4x4"
- Ammo4x4x4.ent = "acf_ammo"
- Ammo4x4x4.type = "Ammo"
- Ammo4x4x4.name = "Modular Ammo Crate"
- Ammo4x4x4.desc = "Modular Ammo Crate 4x4x4 Size\n"
- Ammo4x4x4.model = "models/ammocrates/ammocrate_4x4x4.mdl"
- Ammo4x4x4.weight = 320
-AmmoTable["Ammo4x4x4"] = Ammo4x4x4
-
-local Ammo4x4x6 = {}
- Ammo4x4x6.id = "Ammo4x4x6"
- Ammo4x4x6.ent = "acf_ammo"
- Ammo4x4x6.type = "Ammo"
- Ammo4x4x6.name = "Modular Ammo Crate"
- Ammo4x4x6.desc = "Modular Ammo Crate 4x4x6 Size\n"
- Ammo4x4x6.model = "models/ammocrates/ammocrate_4x4x6.mdl"
- Ammo4x4x6.weight = 480
-AmmoTable["Ammo4x4x6"] = Ammo4x4x6
-
-local Ammo4x4x8 = {}
- Ammo4x4x8.id = "Ammo4x4x8"
- Ammo4x4x8.ent = "acf_ammo"
- Ammo4x4x8.type = "Ammo"
- Ammo4x4x8.name = "Modular Ammo Crate"
- Ammo4x4x8.desc = "Modular Ammo Crate 4x4x8 Size\n"
- Ammo4x4x8.model = "models/ammocrates/ammocrate_4x4x8.mdl"
- Ammo4x4x8.weight = 640
-AmmoTable["Ammo4x4x8"] = Ammo4x4x8
-
-list.Set( "ACFEnts", "Ammo", AmmoTable ) --end ammo containers listing
diff --git a/lua/ACF/Shared/ACFMobilityList.lua b/lua/ACF/Shared/ACFMobilityList.lua
deleted file mode 100644
index cc33e77fa..000000000
--- a/lua/ACF/Shared/ACFMobilityList.lua
+++ /dev/null
@@ -1,3439 +0,0 @@
-AddCSLuaFile( "acf/shared/acfmobilitylist.lua" )
-
-local MobilityTable = {} --Start mobility listing
-
---Gearbox Variables (made this so i don't make errors when adjusting every fucking gearbox)
-
---Overall Gearbox size torque limits
-local GearSMT = 550
-local GearMMT = 1900
-local GearLMT = 10000
-local GearTDSMT = 800 --Max torque for 1/2 speed smalls
-
---1 speed weights
-local Gear1SW = 10
-local Gear1MW = 20
-local Gear1LW = 40
-
---2 speed weights
-local Gear2SW = 20
-local Gear2MW = 40
-local Gear2LW = 80
-
---4 speed weights
-local Gear4SW = 40
-local Gear4MW = 80
-local Gear4LW = 160
-
---6 speed weights
-local Gear6SW = 60
-local Gear6MW = 120
-local Gear6LW = 240
-
---8 speed weights
-local Gear8SW = 80
-local Gear8MW = 160
-local Gear8LW = 320
-
-
-
-
---fix 6.5l i6 sound & 1l sound
-
--- Gas Turbines
-local EngineGTsmall = {}
- EngineGTsmall.id = "Turbine-Small"
- EngineGTsmall.ent = "acf_engine"
- EngineGTsmall.type = "Mobility"
- EngineGTsmall.name = "Gas Turbine, Small"
- EngineGTsmall.desc = "A small gas turbine, high power and a very wide powerband\n\nTurbines are powerful but suffer from poor throttle response."
- EngineGTsmall.model = "models/engines/gasturbine_s.mdl"
- EngineGTsmall.sound = "ACF_engines/turbine_small.wav"
- EngineGTsmall.category = "Turbine"
- EngineGTsmall.weight = 150
- EngineGTsmall.torque = 300
- EngineGTsmall.flywheelmass = 1 --in Meter/Kg
- EngineGTsmall.idlerpm = 2000 --in Rotations Per Minute
- EngineGTsmall.peakminrpm = 1
- EngineGTsmall.peakmaxrpm = 1
- EngineGTsmall.limitprm = 15000
- EngineGTsmall.iselec = true
- EngineGTsmall.elecpower = 134
- EngineGTsmall.flywheeloverride = 6000
-
- if ( CLIENT ) then
- EngineGTsmall.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- EngineGTsmall.guiupdate = function() return end
- end
-MobilityTable["Turbine-Small"] = EngineGTsmall
-
-local EngineGTMedium = {}
- EngineGTMedium.id = "Turbine-Medium"
- EngineGTMedium.ent = "acf_engine"
- EngineGTMedium.type = "Mobility"
- EngineGTMedium.name = "Gas Turbine, Medium"
- EngineGTMedium.desc = "A medium gas turbine, moderate power but a very wide powerband\n\nTurbines are powerful but suffer from poor throttle response."
- EngineGTMedium.model = "models/engines/gasturbine_m.mdl"
- EngineGTMedium.sound = "ACF_engines/turbine_medium.wav"
- EngineGTMedium.category = "Turbine"
- EngineGTMedium.weight = 400
- EngineGTMedium.torque = 600
- EngineGTMedium.flywheelmass = 2 --in Meter/Kg
- EngineGTMedium.idlerpm = 2000 --in Rotations Per Minute
- EngineGTMedium.peakminrpm = 1
- EngineGTMedium.peakmaxrpm = 1
- EngineGTMedium.limitprm = 12000
- EngineGTMedium.iselec = true
- EngineGTMedium.elecpower = 248
- EngineGTMedium.flywheeloverride = 6000
-
-
- if ( CLIENT ) then
- EngineGTMedium.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- EngineGTMedium.guiupdate = function() return end
- end
-MobilityTable["Turbine-Medium"] = EngineGTMedium
-
-local EngineGTLarge = {}
- EngineGTLarge.id = "Turbine-Large"
- EngineGTLarge.ent = "acf_engine"
- EngineGTLarge.type = "Mobility"
- EngineGTLarge.name = "Gas Turbine, Large"
- EngineGTLarge.desc = "A large gas turbine, powerful with a wide powerband\n\nTurbines are powerful but suffer from poor throttle response."
- EngineGTLarge.model = "models/engines/gasturbine_l.mdl"
- EngineGTLarge.sound = "ACF_engines/turbine_large.wav"
- EngineGTLarge.category = "Turbine"
- EngineGTLarge.weight = 1000
- EngineGTLarge.torque = 1500
- EngineGTLarge.flywheelmass = 4 --in Meter/Kg
- EngineGTLarge.idlerpm = 2000 --in Rotations Per Minute
- EngineGTLarge.peakminrpm = 1
- EngineGTLarge.peakmaxrpm = 1
- EngineGTLarge.limitprm = 13500
- EngineGTLarge.iselec = true
- EngineGTLarge.elecpower = 700
- EngineGTLarge.flywheeloverride = 6000
-
- if ( CLIENT ) then
- EngineGTLarge.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- EngineGTLarge.guiupdate = function() return end
- end
-MobilityTable["Turbine-Large"] = EngineGTLarge
-
---Electric motors
-local EngineEsmall = {}
- EngineEsmall.id = "Electric-Small"
- EngineEsmall.ent = "acf_engine"
- EngineEsmall.type = "Mobility"
- EngineEsmall.name = "Electric motor, Small"
- EngineEsmall.desc = "A small electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy"
- EngineEsmall.model = "models/engines/emotorsmall.mdl"
- EngineEsmall.sound = "ACF_engines/electric_small.wav"
- EngineEsmall.category = "Electric"
- EngineEsmall.weight = 350
- EngineEsmall.torque = 400
- EngineEsmall.flywheelmass = 0.25 --in Meter/Kg
- EngineEsmall.idlerpm = 10 --in Rotations Per Minute
- EngineEsmall.peakminrpm = 10
- EngineEsmall.peakmaxrpm = 10
- EngineEsmall.limitprm = 10000
- EngineEsmall.iselec = true
- EngineEsmall.elecpower = 98
- EngineEsmall.flywheeloverride = 5000 --Peakmax override so the flywheel drag function will operate properly for Electrics/turbines
-
-
- if ( CLIENT ) then
- EngineEsmall.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- EngineEsmall.guiupdate = function() return end
- end
-MobilityTable["Electric-Small"] = EngineEsmall
-
-local EngineEmedium = {}
- EngineEmedium.id = "Electric-Medium"
- EngineEmedium.ent = "acf_engine"
- EngineEmedium.type = "Mobility"
- EngineEmedium.name = "Electric motor, Medium"
- EngineEmedium.desc = "A medium electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy"
- EngineEmedium.model = "models/engines/emotormed.mdl"
- EngineEmedium.sound = "ACF_engines/electric_medium.wav"
- EngineEmedium.category = "Electric"
- EngineEmedium.weight = 1000
- EngineEmedium.torque = 1200
- EngineEmedium.flywheelmass = 1.2 --in Meter/Kg
- EngineEmedium.idlerpm = 10 --in Rotations Per Minute
- EngineEmedium.peakminrpm = 10
- EngineEmedium.peakmaxrpm = 10
- EngineEmedium.limitprm = 7000
- EngineEmedium.iselec = true
- EngineEmedium.elecpower = 208
- EngineEmedium.flywheeloverride = 8000 --Peakmax override so the flywheel drag function will operate properly for Electrics/turbines
-
-
-
- if ( CLIENT ) then
- EngineEmedium.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- EngineEmedium.guiupdate = function() return end
- end
-MobilityTable["Electric-Medium"] = EngineEmedium
-
-local EngineElarge = {}
- EngineElarge.id = "Electric-Large"
- EngineElarge.ent = "acf_engine"
- EngineElarge.type = "Mobility"
- EngineElarge.name = "Electric motor, Large"
- EngineElarge.desc = "A huge electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy"
- EngineElarge.model = "models/engines/emotorlarge.mdl"
- EngineElarge.sound = "ACF_engines/electric_large.wav"
- EngineElarge.category = "Electric"
- EngineElarge.weight = 2000
- EngineElarge.torque = 3000
- EngineElarge.flywheelmass = 8 --in Meter/Kg
- EngineElarge.idlerpm = 10 --in Rotations Per Minute
- EngineElarge.peakminrpm = 10
- EngineElarge.peakmaxrpm = 10
- EngineElarge.limitprm = 4500
- EngineElarge.iselec = true
- EngineElarge.elecpower = 340
- EngineElarge.flywheeloverride = 6000 --Peakmax override so the flywheel drag function will operate properly for Electrics/turbines
-
-
- if ( CLIENT ) then
- EngineElarge.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- EngineElarge.guiupdate = function() return end
- end
-MobilityTable["Electric-Large"] = EngineElarge
-
-
---Single cylinders
-local Engine2I1 = {}
- Engine2I1.id = "0.25-I1"
- Engine2I1.ent = "acf_engine"
- Engine2I1.type = "Mobility"
- Engine2I1.name = "250cc Single"
- Engine2I1.desc = "Tiny bike engine"
- Engine2I1.model = "models/engines/1cyls.mdl"
- Engine2I1.sound = "acf_engines/i1_small.wav"
- Engine2I1.category = "Single"
- Engine2I1.weight = 15
- Engine2I1.torque = 20 --in Meter/Kg
- Engine2I1.flywheelmass = 0.005
-
- Engine2I1.idlerpm = 1200 --in Rotations Per Minute
- Engine2I1.peakminrpm = 4000
- Engine2I1.peakmaxrpm = 6500
- Engine2I1.limitprm = 7500
- if ( CLIENT ) then
- Engine2I1.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine2I1.guiupdate = function() return end
- end
-MobilityTable["0.25-I1"] = Engine2I1
-
-local Engine5I1 = {}
- Engine5I1.id = "0.5-I1"
- Engine5I1.ent = "acf_engine"
- Engine5I1.type = "Mobility"
- Engine5I1.name = "500cc Single"
- Engine5I1.desc = "Large single cylinder bike engine"
- Engine5I1.model = "models/engines/1cylm.mdl"
- Engine5I1.sound = "acf_engines/i1_medium.wav"
- Engine5I1.category = "Single"
- Engine5I1.weight = 30
- Engine5I1.torque = 40 --in Meter/Kg
- Engine5I1.flywheelmass = 0.005
-
- Engine5I1.idlerpm = 900 --in Rotations Per Minute
- Engine5I1.peakminrpm = 4300
- Engine5I1.peakmaxrpm = 7000
- Engine5I1.limitprm = 8000
- if ( CLIENT ) then
- Engine5I1.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine5I1.guiupdate = function() return end
- end
-MobilityTable["0.5-I1"] = Engine5I1
-
-local Engine13I1 = {}
- Engine13I1.id = "1.3-I1"
- Engine13I1.ent = "acf_engine"
- Engine13I1.type = "Mobility"
- Engine13I1.name = "1300cc Single"
- Engine13I1.desc = "Ridiculously large single cylinder engine, seriously what the fuck"
- Engine13I1.model = "models/engines/1cylb.mdl"
- Engine13I1.sound = "acf_engines/i1_large.wav"
- Engine13I1.category = "Single"
- Engine13I1.weight = 55
- Engine13I1.torque = 90 --in Meter/Kg
- Engine13I1.flywheelmass = 0.1
-
- Engine13I1.idlerpm = 600 --in Rotations Per Minute
- Engine13I1.peakminrpm = 3600
- Engine13I1.peakmaxrpm = 6000
- Engine13I1.limitprm = 6700
- if ( CLIENT ) then
- Engine13I1.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine13I1.guiupdate = function() return end
- end
-MobilityTable["1.3-I1"] = Engine13I1
-
---Vtwins
-local Engine6V2 = {}
- Engine6V2.id = "0.6-V2"
- Engine6V2.ent = "acf_engine"
- Engine6V2.type = "Mobility"
- Engine6V2.name = "600cc V-Twin"
- Engine6V2.desc = "Twin cylinder bike engine, torquey for its size"
- Engine6V2.model = "models/engines/v-twins.mdl"
- Engine6V2.sound = "acf_engines/vtwin_small.wav"
- Engine6V2.category = "V-Twin"
- Engine6V2.weight = 40
- Engine6V2.torque = 50 --in Meter/Kg
- Engine6V2.flywheelmass = 0.01
-
- Engine6V2.idlerpm = 900 --in Rotations Per Minute
- Engine6V2.peakminrpm = 4000
- Engine6V2.peakmaxrpm = 6500
- Engine6V2.limitprm = 7500
- if ( CLIENT ) then
- Engine6V2.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine6V2.guiupdate = function() return end
- end
-MobilityTable["0.6-V2"] = Engine6V2
-
-local Engine12V2 = {}
- Engine12V2.id = "1.2-V2"
- Engine12V2.ent = "acf_engine"
- Engine12V2.type = "Mobility"
- Engine12V2.name = "1200cc V-Twin"
- Engine12V2.desc = "Large displacement vtwin engine"
- Engine12V2.model = "models/engines/v-twinm.mdl"
- Engine12V2.sound = "acf_engines/vtwin_medium.wav"
- Engine12V2.category = "V-Twin"
- Engine12V2.weight = 60
- Engine12V2.torque = 85 --in Meter/Kg
- Engine12V2.flywheelmass = 0.02
-
- Engine12V2.idlerpm = 725 --in Rotations Per Minute
- Engine12V2.peakminrpm = 3300
- Engine12V2.peakmaxrpm = 5500
- Engine12V2.limitprm = 6250
- if ( CLIENT ) then
- Engine12V2.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine12V2.guiupdate = function() return end
- end
-MobilityTable["1.2-V2"] = Engine12V2
-
-local Engine24V2 = {}
- Engine24V2.id = "2.4-V2"
- Engine24V2.ent = "acf_engine"
- Engine24V2.type = "Mobility"
- Engine24V2.name = "2400cc V-Twin"
- Engine24V2.desc = "Huge fucking Vtwin 'MURRICA FUCK YEAH"
- Engine24V2.model = "models/engines/v-twinb.mdl"
- Engine24V2.sound = "acf_engines/vtwin_large.wav"
- Engine24V2.category = "V-Twin"
- Engine24V2.weight = 120
- Engine24V2.torque = 160 --in Meter/Kg
- Engine24V2.flywheelmass = 0.075
-
- Engine24V2.idlerpm = 900 --in Rotations Per Minute
- Engine24V2.peakminrpm = 3300
- Engine24V2.peakmaxrpm = 5500
- Engine24V2.limitprm = 6500
- if ( CLIENT ) then
- Engine24V2.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine24V2.guiupdate = function() return end
- end
-MobilityTable["2.4-V2"] = Engine24V2
-
-
-
-
--- Petrol I4s
-local Engine15I4 = {}
- Engine15I4.id = "1.5-I4"
- Engine15I4.ent = "acf_engine"
- Engine15I4.type = "Mobility"
- Engine15I4.name = "1.5L I4 Petrol"
- Engine15I4.desc = "Small car engine, not a whole lot of git"
- Engine15I4.model = "models/engines/inline4s.mdl"
- Engine15I4.sound = "ACF_engines/i4_petrolsmall2.wav"
- Engine15I4.category = "I4"
- Engine15I4.weight = 125
- Engine15I4.torque = 90 --in Meter/Kg
- Engine15I4.flywheelmass = 0.06
- Engine15I4.powermod = 1
-
- Engine15I4.idlerpm = 900 --in Rotations Per Minute
- Engine15I4.peakminrpm = 4000
- Engine15I4.peakmaxrpm = 6500
- Engine15I4.limitprm = 7500
- if ( CLIENT ) then
- Engine15I4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine15I4.guiupdate = function() return end
- end
-MobilityTable["1.5-I4"] = Engine15I4
-
-local Engine37I4 = {}
- Engine37I4.id = "3.7-I4"
- Engine37I4.ent = "acf_engine"
- Engine37I4.type = "Mobility"
- Engine37I4.name = "3.7L I4 Petrol"
- Engine37I4.desc = "Large inline 4, sees most use in light trucks"
- Engine37I4.model = "models/engines/inline4m.mdl"
- Engine37I4.sound = "ACF_engines/i4_petrolmedium2.wav"
- Engine37I4.category = "I4"
- Engine37I4.weight = 250
- Engine37I4.torque = 300 --in Meter/Kg
- Engine37I4.flywheelmass = 0.2
-
- Engine37I4.idlerpm = 900 --in Rotations Per Minute
- Engine37I4.peakminrpm = 3700
- Engine37I4.peakmaxrpm = 6000
- Engine37I4.limitprm = 6000
- if ( CLIENT ) then
- Engine37I4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine37I4.guiupdate = function() return end
- end
-MobilityTable["3.7-I4"] = Engine37I4
-
-local Engine160I4 = {}
- Engine160I4.id = "16.0-I4"
- Engine160I4.ent = "acf_engine"
- Engine160I4.type = "Mobility"
- Engine160I4.name = "16.0L I4 Petrol"
- Engine160I4.desc = "Giant, thirsty I4 petrol, most commonly used in boats"
- Engine160I4.model = "models/engines/inline4l.mdl"
- Engine160I4.sound = "ACF_engines/i4_petrollarge.wav"
- Engine160I4.category = "I4"
- Engine160I4.weight = 800
- Engine160I4.torque = 950 --in Meter/Kg
- Engine160I4.flywheelmass = 1.5
-
- Engine160I4.idlerpm = 500 --in Rotations Per Minute
- Engine160I4.peakminrpm = 1750
- Engine160I4.peakmaxrpm = 3250
- Engine160I4.limitprm = 3500
- if ( CLIENT ) then
- Engine160I4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine160I4.guiupdate = function() return end
- end
-MobilityTable["16.0-I4"] = Engine160I4
-
-
-
-
--- Diesel I4s
-local Engine16I4 = {}
- Engine16I4.id = "1.6-I4"
- Engine16I4.ent = "acf_engine"
- Engine16I4.type = "Mobility"
- Engine16I4.name = "1.6L I4 Diesel"
- Engine16I4.desc = "Small and light diesel, for low power applications requiring a wide powerband"
- Engine16I4.model = "models/engines/inline4s.mdl"
- Engine16I4.sound = "ACF_engines/i4_diesel2.wav"
- Engine16I4.category = "I4"
- Engine16I4.weight = 150
- Engine16I4.torque = 150 --in Meter/Kg
- Engine16I4.flywheelmass = 0.2
-
- Engine16I4.idlerpm = 650 --in Rotations Per Minute
- Engine16I4.peakminrpm = 1000
- Engine16I4.peakmaxrpm = 3000
- Engine16I4.limitprm = 5000
- if ( CLIENT ) then
- Engine16I4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine16I4.guiupdate = function() return end
- end
-MobilityTable["1.6-I4"] = Engine16I4
-
-local Engine31I4 = {}
- Engine31I4.id = "3.1-I4"
- Engine31I4.ent = "acf_engine"
- Engine31I4.type = "Mobility"
- Engine31I4.name = "3.1L I4 Diesel"
- Engine31I4.desc = "Light truck duty diesel, good overall grunt"
- Engine31I4.model = "models/engines/inline4m.mdl"
- Engine31I4.sound = "ACF_engines/i4_dieselmedium.wav"
- Engine31I4.category = "I4"
- Engine31I4.weight = 350
- Engine31I4.torque = 400 --in Meter/Kg
- Engine31I4.flywheelmass = 1
-
- Engine31I4.idlerpm = 500 --in Rotations Per Minute
- Engine31I4.peakminrpm = 1150
- Engine31I4.peakmaxrpm = 3500
- Engine31I4.limitprm = 4000
- if ( CLIENT ) then
- Engine31I4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine31I4.guiupdate = function() return end
- end
-MobilityTable["3.1-I4"] = Engine31I4
-
-local Engine150I4 = {}
- Engine150I4.id = "15.0-I4"
- Engine150I4.ent = "acf_engine"
- Engine150I4.type = "Mobility"
- Engine150I4.name = "15.0L I4 Diesel"
- Engine150I4.desc = "Small boat sized diesel, with large amounts of torque"
- Engine150I4.model = "models/engines/inline4l.mdl"
- Engine150I4.sound = "ACF_engines/i4_diesellarge.wav"
- Engine150I4.category = "I4"
- Engine150I4.weight = 1000
- Engine150I4.torque = 1800 --in Meter/Kg
- Engine150I4.flywheelmass = 5
-
- Engine150I4.idlerpm = 300 --in Rotations Per Minute
- Engine150I4.peakminrpm = 500
- Engine150I4.peakmaxrpm = 1500
- Engine150I4.limitprm = 2000
- if ( CLIENT ) then
- Engine150I4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine150I4.guiupdate = function() return end
- end
-MobilityTable["15.0-I4"] = Engine150I4
-
---Petrol Boxer 4s
-local Engine14B4 = {}
- Engine14B4.id = "1.4-B4"
- Engine14B4.ent = "acf_engine"
- Engine14B4.type = "Mobility"
- Engine14B4.name = "1.4L Flat 4 Petrol"
- Engine14B4.desc = "Small air cooled flat four, most commonly found in nazi insects"
- Engine14B4.model = "models/engines/b4small.mdl"
- Engine14B4.sound = "ACF_engines/b4_petrolsmall.wav"
- Engine14B4.category = "B4"
- Engine14B4.weight = 75
- Engine14B4.torque = 105 --in Meter/Kg
- Engine14B4.flywheelmass = 0.06
-
- Engine14B4.idlerpm = 600 --in Rotations Per Minute
- Engine14B4.peakminrpm = 2600
- Engine14B4.peakmaxrpm = 4200
- Engine14B4.limitprm = 4500
- if ( CLIENT ) then
- Engine14B4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine14B4.guiupdate = function() return end
- end
-MobilityTable["1.4-B4"] = Engine14B4
-
-local Engine21B4 = {}
- Engine21B4.id = "2.1-B4"
- Engine21B4.ent = "acf_engine"
- Engine21B4.type = "Mobility"
- Engine21B4.name = "2.1L Flat 4 Petrol"
- Engine21B4.desc = "Tuned up flat four, probably find this in things that go fast in a desert."
- Engine21B4.model = "models/engines/b4small.mdl"
- Engine21B4.sound = "ACF_engines/b4_petrolmedium.wav"
- Engine21B4.category = "B4"
- Engine21B4.weight = 150
- Engine21B4.torque = 225 --in Meter/Kg
- Engine21B4.flywheelmass = 0.15
-
- Engine21B4.idlerpm = 700 --in Rotations Per Minute
- Engine21B4.peakminrpm = 3000
- Engine21B4.peakmaxrpm = 4800
- Engine21B4.limitprm = 5000
- if ( CLIENT ) then
- Engine21B4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine21B4.guiupdate = function() return end
- end
-MobilityTable["2.1-B4"] = Engine21B4
-
-local Engine32B4 = {}
- Engine32B4.id = "3.2-B4"
- Engine32B4.ent = "acf_engine"
- Engine32B4.type = "Mobility"
- Engine32B4.name = "3.2L Flat 4 Petrol"
- Engine32B4.desc = "Bored out fuckswindleton batshit flat four. Fuck yourself."
- Engine32B4.model = "models/engines/b4med.mdl"
- Engine32B4.sound = "ACF_engines/b4_petrollarge.wav"
- Engine32B4.category = "B4"
- Engine32B4.weight = 200
- Engine32B4.torque = 375 --in Meter/Kg
- Engine32B4.flywheelmass = 0.15
-
- Engine32B4.idlerpm = 900 --in Rotations Per Minute
- Engine32B4.peakminrpm = 3400
- Engine32B4.peakmaxrpm = 5500
- Engine32B4.limitprm = 6500
- if ( CLIENT ) then
- Engine32B4.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine32B4.guiupdate = function() return end
- end
-MobilityTable["3.2-B4"] = Engine32B4
---Petrol Boxer 6s
-
-local Engine28B6 = {}
- Engine28B6.id = "2.8-B6"
- Engine28B6.ent = "acf_engine"
- Engine28B6.type = "Mobility"
- Engine28B6.name = "2.8L Flat 6 Petrol"
- Engine28B6.desc = "Car sized flat six engine, sporty and light"
- Engine28B6.model = "models/engines/b6small.mdl"
- Engine28B6.sound = "ACF_engines/b6_petrolsmall.wav"
- Engine28B6.category = "B6"
- Engine28B6.weight = 200
- Engine28B6.torque = 170 --in Meter/Kg
- Engine28B6.flywheelmass = 0.08
-
- Engine28B6.idlerpm = 750 --in Rotations Per Minute
- Engine28B6.peakminrpm = 4300
- Engine28B6.peakmaxrpm = 6950
- Engine28B6.limitprm = 7250
- if ( CLIENT ) then
- Engine28B6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine28B6.guiupdate = function() return end
- end
-MobilityTable["2.8-B6"] = Engine28B6
-
-local Engine50B6 = {}
- Engine50B6.id = "5.0-B6"
- Engine50B6.ent = "acf_engine"
- Engine50B6.type = "Mobility"
- Engine50B6.name = "5.0 Flat 6 Petrol"
- Engine50B6.desc = "Sports car grade flat six, renown for their smooth operation and light weight"
- Engine50B6.model = "models/engines/b6med.mdl"
- Engine50B6.sound = "ACF_engines/b6_petrolmedium.wav"
- Engine50B6.category = "B6"
- Engine50B6.weight = 275
- Engine50B6.torque = 360 --in Meter/Kg
- Engine50B6.flywheelmass = 0.1
-
- Engine50B6.idlerpm = 900 --in Rotations Per Minute
- Engine50B6.peakminrpm = 3500
- Engine50B6.peakmaxrpm = 6000
- Engine50B6.limitprm = 6800
- if ( CLIENT ) then
- Engine50B6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine50B6.guiupdate = function() return end
- end
-MobilityTable["5.0-B6"] = Engine50B6
-
-local Engine10B6 = {}
- Engine10B6.id = "10.0-B6"
- Engine10B6.ent = "acf_engine"
- Engine10B6.type = "Mobility"
- Engine10B6.name = "10.0L Flat 6 Petrol"
- Engine10B6.desc = "Aircraft grade boxer with a high rev range biased powerband"
- Engine10B6.model = "models/engines/b6large.mdl"
- Engine10B6.sound = "ACF_engines/b6_petrollarge.wav"
- Engine10B6.category = "B6"
- Engine10B6.weight = 600
- Engine10B6.torque = 900 --in Meter/Kg
- Engine10B6.flywheelmass = 1
-
- Engine10B6.idlerpm = 620 --in Rotations Per Minute
- Engine10B6.peakminrpm = 2500
- Engine10B6.peakmaxrpm = 4100
- Engine10B6.limitprm = 4500
- if ( CLIENT ) then
- Engine10B6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine10B6.guiupdate = function() return end
- end
-MobilityTable["10.0-B6"] = Engine10B6
-
---Petrol V6s
-
-local Engine36V6 = {}
- Engine36V6.id = "3.6-V6"
- Engine36V6.ent = "acf_engine"
- Engine36V6.type = "Mobility"
- Engine36V6.name = "3.6L V6 Petrol"
- Engine36V6.desc = "Meaty Car sized V6, lots of torque/n/nV6s are more torquey than the Boxer and Inline 6s but suffer in power"
- Engine36V6.model = "models/engines/v6small.mdl"
- Engine36V6.sound = "ACF_engines/v6_petrolsmall.wav"
- Engine36V6.category = "V6"
- Engine36V6.weight = 280
- Engine36V6.torque = 285 --in Meter/Kg
- Engine36V6.flywheelmass = 0.25
-
- Engine36V6.idlerpm = 700 --in Rotations Per Minute
- Engine36V6.peakminrpm = 2200
- Engine36V6.peakmaxrpm = 3500
- Engine36V6.limitprm = 5500
- if ( CLIENT ) then
- Engine36V6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine36V6.guiupdate = function() return end
- end
-MobilityTable["3.6-V6"] = Engine36V6
-
-local Engine62V6 = {}
- Engine62V6.id = "6.2-V6"
- Engine62V6.ent = "acf_engine"
- Engine62V6.type = "Mobility"
- Engine62V6.name = "6.2L V6 Petrol"
- Engine62V6.desc = "Heavy duty v6, throatier than an LA whore, but loaded with torque/n/nV6s are more torquey than the Boxer and Inline 6s but suffer in power"
- Engine62V6.model = "models/engines/v6med.mdl"
- Engine62V6.sound = "ACF_engines/v6_petrolmedium.wav"
- Engine62V6.category = "V6"
- Engine62V6.weight = 450
- Engine62V6.torque = 525 --in Meter/Kg
- Engine62V6.flywheelmass = 0.45
-
- Engine62V6.idlerpm = 800 --in Rotations Per Minute
- Engine62V6.peakminrpm = 2200
- Engine62V6.peakmaxrpm = 3600
- Engine62V6.limitprm = 6000
- if ( CLIENT ) then
- Engine62V6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine62V6.guiupdate = function() return end
- end
-MobilityTable["6.2-V6"] = Engine62V6
-
-local Engine120V6 = {}
- Engine120V6.id = "12.0-V6"
- Engine120V6.ent = "acf_engine"
- Engine120V6.type = "Mobility"
- Engine120V6.name = "12.0L V6 Petrol"
- Engine120V6.desc = "Fuck duty V6, guts ripped from god himself diluted in salt and shaped into an engine./n/nV6s are more torquey than the Boxer and Inline 6s but suffer in power"
- Engine120V6.model = "models/engines/v6large.mdl"
- Engine120V6.sound = "ACF_engines/v6_petrollarge.wav"
- Engine120V6.category = "V6"
- Engine120V6.weight = 750
- Engine120V6.torque = 1300 --in Meter/Kg
- Engine120V6.flywheelmass = 2.5
-
- Engine120V6.idlerpm = 600 --in Rotations Per Minute
- Engine120V6.peakminrpm = 1750
- Engine120V6.peakmaxrpm = 2950
- Engine120V6.limitprm = 3500
- if ( CLIENT ) then
- Engine120V6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine120V6.guiupdate = function() return end
- end
-MobilityTable["12.0-V6"] = Engine120V6
-
---Diesel L6s
-local Engine30I6 = {}
- Engine30I6.id = "3.0-I6"
- Engine30I6.ent = "acf_engine"
- Engine30I6.type = "Mobility"
- Engine30I6.name = "3.0L I6 Diesel"
- Engine30I6.desc = "Car sized I6 diesel, good, wide powerband"
- Engine30I6.model = "models/engines/inline6s.mdl"
- Engine30I6.sound = "ACF_engines/l6_dieselsmall.wav"
- Engine30I6.category = "I6"
- Engine30I6.weight = 300
- Engine30I6.torque = 240 --in Meter/Kg
- Engine30I6.flywheelmass = 0.5
-
- Engine30I6.idlerpm = 650 --in Rotations Per Minute
- Engine30I6.peakminrpm = 1000
- Engine30I6.peakmaxrpm = 3000
- Engine30I6.limitprm = 4500
- if ( CLIENT ) then
- Engine30I6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine30I6.guiupdate = function() return end
- end
-MobilityTable["3.0-I6"] = Engine30I6
-
-local Engine65I6 = {}
- Engine65I6.id = "6.5-I6"
- Engine65I6.ent = "acf_engine"
- Engine65I6.type = "Mobility"
- Engine65I6.name = "6.5L I6 Diesel"
- Engine65I6.desc = "Truck duty I6, good overall powerband and torque"
- Engine65I6.model = "models/engines/inline6m.mdl"
- Engine65I6.sound = "ACF_engines/l6_dieselmedium4.wav"
- Engine65I6.category = "I6"
- Engine65I6.weight = 650
- Engine65I6.torque = 550 --in Meter/Kg
- Engine65I6.flywheelmass = 1.5
-
- Engine65I6.idlerpm = 600 --in Rotations Per Minute
- Engine65I6.peakminrpm = 1100
- Engine65I6.peakmaxrpm = 3500
- Engine65I6.limitprm = 4000
- if ( CLIENT ) then
- Engine65I6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine65I6.guiupdate = function() return end
- end
-MobilityTable["6.5-I6"] = Engine65I6
-
-local Engine200I6 = {}
- Engine200I6.id = "20.0-I6"
- Engine200I6.ent = "acf_engine"
- Engine200I6.type = "Mobility"
- Engine200I6.name = "20.0L I6 Diesel"
- Engine200I6.desc = "Heavy duty diesel I6, used in generators and heavy movers"
- Engine200I6.model = "models/engines/inline6l.mdl"
- Engine200I6.sound = "ACF_engines/l6_diesellarge2.wav"
- Engine200I6.category = "I6"
- Engine200I6.weight = 1000
- Engine200I6.torque = 2000 --in Meter/Kg
- Engine200I6.flywheelmass = 8
-
- Engine200I6.idlerpm = 400 --in Rotations Per Minute
- Engine200I6.peakminrpm = 500
- Engine200I6.peakmaxrpm = 1700
- Engine200I6.limitprm = 2250
- if ( CLIENT ) then
- Engine200I6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine200I6.guiupdate = function() return end
- end
-MobilityTable["20.0-I6"] = Engine200I6
-
-
-
---Petrol L6s
-local Engine22I6 = {}
- Engine22I6.id = "2.2-I6"
- Engine22I6.ent = "acf_engine"
- Engine22I6.type = "Mobility"
- Engine22I6.name = "2.2L I6 Petrol"
- Engine22I6.desc = "Car sized I6 petrol with power in the high revs"
- Engine22I6.model = "models/engines/inline6s.mdl"
- Engine22I6.sound = "ACF_engines/l6_petrolsmall2.wav"
- Engine22I6.category = "I6"
- Engine22I6.weight = 250
- Engine22I6.torque = 190 --in Meter/Kg
- Engine22I6.flywheelmass = 0.1
-
- Engine22I6.idlerpm = 800 --in Rotations Per Minute
- Engine22I6.peakminrpm = 4000
- Engine22I6.peakmaxrpm = 6500
- Engine22I6.limitprm = 7200
- if ( CLIENT ) then
- Engine22I6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine22I6.guiupdate = function() return end
- end
-MobilityTable["2.2-I6"] = Engine22I6
-
-local Engine48I6 = {}
- Engine48I6.id = "4.8-I6"
- Engine48I6.ent = "acf_engine"
- Engine48I6.type = "Mobility"
- Engine48I6.name = "4.8L I6 Petrol"
- Engine48I6.desc = "Light truck duty I6, good for offroad applications"
- Engine48I6.model = "models/engines/inline6m.mdl"
- Engine48I6.sound = "ACF_engines/l6_petrolmedium.wav"
- Engine48I6.category = "I6"
- Engine48I6.weight = 350
- Engine48I6.torque = 400 --in Meter/Kg
- Engine48I6.flywheelmass = 0.2
-
- Engine48I6.idlerpm = 900 --in Rotations Per Minute
- Engine48I6.peakminrpm = 3500
- Engine48I6.peakmaxrpm = 5800
- Engine48I6.limitprm = 6500
- if ( CLIENT ) then
- Engine48I6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine48I6.guiupdate = function() return end
- end
-MobilityTable["4.8-I6"] = Engine48I6
-
-local Engine172I6 = {}
- Engine172I6.id = "17.2-I6"
- Engine172I6.ent = "acf_engine"
- Engine172I6.type = "Mobility"
- Engine172I6.name = "17.2L I6 Petrol"
- Engine172I6.desc = "Heavy tractor duty petrol I6, decent overall powerband"
- Engine172I6.model = "models/engines/inline6l.mdl"
- Engine172I6.sound = "ACF_engines/l6_petrollarge2.wav"
- Engine172I6.category = "I6"
- Engine172I6.weight = 700
- Engine172I6.torque = 1200 --in Meter/Kg
- Engine172I6.flywheelmass = 2.5
-
- Engine172I6.idlerpm = 800 --in Rotations Per Minute
- Engine172I6.peakminrpm = 2000
- Engine172I6.peakmaxrpm = 3300
- Engine172I6.limitprm = 4000
- if ( CLIENT ) then
- Engine172I6.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine172I6.guiupdate = function() return end
- end
-MobilityTable["17.2-I6"] = Engine172I6
-
-
-
-
---Diesel V12s
-
-local Engine40V12 = {}
- Engine40V12.id = "4.0-V12"
- Engine40V12.ent = "acf_engine"
- Engine40V12.type = "Mobility"
- Engine40V12.name = "4.0L V12 Diesel"
- Engine40V12.desc = "An old V12; not much power, but a lot of smooth torque"
- Engine40V12.model = "models/engines/v12s.mdl"
- Engine40V12.sound = "ACF_engines/v12_dieselsmall.wav"
- Engine40V12.category = "V12"
- Engine40V12.weight = 400
- Engine40V12.torque = 400 --in Meter/Kg
- Engine40V12.flywheelmass = 0.475
-
- Engine40V12.idlerpm = 650 --in Rotations Per Minute
- Engine40V12.peakminrpm = 1200
- Engine40V12.peakmaxrpm = 3800
- Engine40V12.limitprm = 4000
- if ( CLIENT ) then
- Engine40V12.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine40V12.guiupdate = function() return end
- end
-MobilityTable["4.0-V12"] = Engine40V12
-
-local Engine92V12 = {}
- Engine92V12.id = "9.2-V12"
- Engine92V12.ent = "acf_engine"
- Engine92V12.type = "Mobility"
- Engine92V12.name = "9.2L V12 Diesel"
- Engine92V12.desc = "High torque V12, used mainly for vehicles that require balls"
- Engine92V12.model = "models/engines/v12m.mdl"
- Engine92V12.sound = "ACF_engines/v12_dieselmedium.wav"
- Engine92V12.category = "V12"
- Engine92V12.weight = 900
- Engine92V12.torque = 1000 --in Meter/Kg
- Engine92V12.flywheelmass = 2.5
-
- Engine92V12.idlerpm = 675 --in Rotations Per Minute
- Engine92V12.peakminrpm = 1100
- Engine92V12.peakmaxrpm = 3300
- Engine92V12.limitprm = 3500
- if ( CLIENT ) then
- Engine92V12.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine92V12.guiupdate = function() return end
- end
-MobilityTable["9.2-V12"] = Engine92V12
-
-local Engine210V12 = {}
- Engine210V12.id = "21.0-V12"
- Engine210V12.ent = "acf_engine"
- Engine210V12.type = "Mobility"
- Engine210V12.name = "21.0 V12 Diesel"
- Engine210V12.desc = "Extreme duty V12; however massively powerful, it is enormous and heavy"
- Engine210V12.model = "models/engines/v12l.mdl"
- Engine210V12.sound = "ACF_engines/v12_diesellarge.wav"
- Engine210V12.category = "V12"
- Engine210V12.weight = 1500
- Engine210V12.torque = 2800 --in Meter/Kg
- Engine210V12.flywheelmass = 7
-
- Engine210V12.idlerpm = 400 --in Rotations Per Minute
- Engine210V12.peakminrpm = 500
- Engine210V12.peakmaxrpm = 1500
- Engine210V12.limitprm = 2500
- if ( CLIENT ) then
- Engine210V12.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine210V12.guiupdate = function() return end
- end
-MobilityTable["21.0-V12"] = Engine210V12
-
-
-
---Petrol V12s
-local Engine46V12 = {}
- Engine46V12.id = "4.6-V12"
- Engine46V12.ent = "acf_engine"
- Engine46V12.type = "Mobility"
- Engine46V12.name = "4.6L V12 Petrol"
- Engine46V12.desc = "An old racing engine; low on torque, but plenty of power"
- Engine46V12.model = "models/engines/v12s.mdl"
- Engine46V12.sound = "ACF_engines/v12_petrolsmall.wav"
- Engine46V12.category = "V12"
- Engine46V12.weight = 300
- Engine46V12.torque = 250 --in Meter/Kg
- Engine46V12.flywheelmass = 0.2
-
- Engine46V12.idlerpm = 1000 --in Rotations Per Minute
- Engine46V12.peakminrpm = 4500
- Engine46V12.peakmaxrpm = 7500
- Engine46V12.limitprm = 8000
- if ( CLIENT ) then
- Engine46V12.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine46V12.guiupdate = function() return end
- end
-MobilityTable["4.6-V12"] = Engine46V12
-
-local Engine70V12 = {}
- Engine70V12.id = "7.0-V12"
- Engine70V12.ent = "acf_engine"
- Engine70V12.type = "Mobility"
- Engine70V12.name = "7.0L V12 Petrol"
- Engine70V12.desc = "A high end V12; primarily found in very expensive cars"
- Engine70V12.model = "models/engines/v12m.mdl"
- Engine70V12.sound = "ACF_engines/v12_petrolmedium.wav"
- Engine70V12.category = "V12"
- Engine70V12.weight = 450
- Engine70V12.torque = 520 --in Meter/Kg
- Engine70V12.flywheelmass = 0.450
-
- Engine70V12.idlerpm = 800 --in Rotations Per Minute
- Engine70V12.peakminrpm = 3600
- Engine70V12.peakmaxrpm = 6000
- Engine70V12.limitprm = 7500
- if ( CLIENT ) then
- Engine70V12.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine70V12.guiupdate = function() return end
- end
-MobilityTable["7.0-V12"] = Engine70V12
-
-local Engine230V12 = {}
- Engine230V12.id = "23.0-V12"
- Engine230V12.ent = "acf_engine"
- Engine230V12.type = "Mobility"
- Engine230V12.name = "23.0 V12 Petrol"
- Engine230V12.desc = "A large, thirsty gasoline V12, likes to break down and roast crewmen"
- Engine230V12.model = "models/engines/v12l.mdl"
- Engine230V12.sound = "ACF_engines/v12_petrollarge.wav"
- Engine230V12.category = "V12"
- Engine230V12.weight = 1300
- Engine230V12.torque = 1800 --in Meter/Kg
- Engine230V12.flywheelmass = 5
-
- Engine230V12.idlerpm = 600 --in Rotations Per Minute
- Engine230V12.peakminrpm = 1500
- Engine230V12.peakmaxrpm = 3000
- Engine230V12.limitprm = 3000
- if ( CLIENT ) then
- Engine230V12.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine230V12.guiupdate = function() return end
- end
-MobilityTable["23.0-V12"] = Engine230V12
-
-
-
-
---Petrol Radials
-local Engine38R7 = {}
- Engine38R7.id = "3.8-R7"
- Engine38R7.ent = "acf_engine"
- Engine38R7.type = "Mobility"
- Engine38R7.name = "3.8L R7 Petrol"
- Engine38R7.desc = "A tiny, old worn-out radial."
- Engine38R7.model = "models/engines/radial7s.mdl"
- Engine38R7.sound = "ACF_engines/R7_petrolsmall.wav"
- Engine38R7.category = "Radial"
- Engine38R7.weight = 150
- Engine38R7.torque = 250 --in Meter/Kg
- Engine38R7.flywheelmass = 0.15
-
- Engine38R7.idlerpm = 700 --in Rotations Per Minute
- Engine38R7.peakminrpm = 2800
- Engine38R7.peakmaxrpm = 4500
- Engine38R7.limitprm = 5000
- if ( CLIENT ) then
- Engine38R7.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine38R7.guiupdate = function() return end
- end
-MobilityTable["3.8-R7"] = Engine38R7
-
-local Engine11R7 = {}
- Engine11R7.id = "11.0-R7"
- Engine11R7.ent = "acf_engine"
- Engine11R7.type = "Mobility"
- Engine11R7.name = "11.0 R7 Petrol"
- Engine11R7.desc = "Mid range radial, thirsty and smooth"
- Engine11R7.model = "models/engines/radial7m.mdl"
- Engine11R7.sound = "ACF_engines/R7_petrolmedium.wav"
- Engine11R7.category = "Radial"
- Engine11R7.weight = 350
- Engine11R7.torque = 550 --in Meter/Kg
- Engine11R7.flywheelmass = 0.350
-
- Engine11R7.idlerpm = 600 --in Rotations Per Minute
- Engine11R7.peakminrpm = 2200
- Engine11R7.peakmaxrpm = 3700
- Engine11R7.limitprm = 3700
- if ( CLIENT ) then
- Engine11R7.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine11R7.guiupdate = function() return end
- end
-MobilityTable["11.0-R7"] = Engine11R7
-
-local Engine240R7 = {}
- Engine240R7.id = "24.0-R7"
- Engine240R7.ent = "acf_engine"
- Engine240R7.type = "Mobility"
- Engine240R7.name = "24.0L R7 Petrol"
- Engine240R7.desc = "The beast of Radials, this monster was destined for fighter aircraft."
- Engine240R7.model = "models/engines/radial7l.mdl"
- Engine240R7.sound = "ACF_engines/R7_petrollarge.wav"
- Engine240R7.category = "Radial"
- Engine240R7.weight = 800
- Engine240R7.torque = 1600 --in Meter/Kg
- Engine240R7.flywheelmass = 3
-
- Engine240R7.idlerpm = 750 --in Rotations Per Minute
- Engine240R7.peakminrpm = 1900
- Engine240R7.peakmaxrpm = 3000
- Engine240R7.limitprm = 3000
- if ( CLIENT ) then
- Engine240R7.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine240R7.guiupdate = function() return end
- end
-MobilityTable["24.0-R7"] = Engine240R7
-
-
-
-
-
---Petrol V8s
-local Engine180V8 = {}
- Engine180V8.id = "18.0-V8"
- Engine180V8.ent = "acf_engine"
- Engine180V8.type = "Mobility"
- Engine180V8.name = "18.0L V8 Petrol"
- Engine180V8.desc = "American Ford GAA V8, decent overall power and torque and fairly lightweight"
- Engine180V8.model = "models/engines/v8l.mdl"
- Engine180V8.sound = "ACF_engines/v8_petrollarge.wav"
- Engine180V8.category = "V8"
- Engine180V8.weight = 900
- Engine180V8.torque = 1420 --in Meter/Kg
- Engine180V8.flywheelmass = 2.8
-
- Engine180V8.idlerpm = 600 --in Rotations Per Minute
- Engine180V8.peakminrpm = 1800
- Engine180V8.peakmaxrpm = 3000
- Engine180V8.limitprm = 3800
- if ( CLIENT ) then
- Engine180V8.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine180V8.guiupdate = function() return end
- end
-MobilityTable["18.0-V8"] = Engine180V8
-
-local Engine90V8 = {}
- Engine90V8.id = "9.0-V8"
- Engine90V8.ent = "acf_engine"
- Engine90V8.type = "Mobility"
- Engine90V8.name = "9.0L V8 Petrol"
- Engine90V8.desc = "Thirsty, giant V8, for medium applications"
- Engine90V8.model = "models/engines/v8m.mdl"
- Engine90V8.sound = "ACF_engines/v8_petrolmedium.wav"
- Engine90V8.category = "V8"
- Engine90V8.weight = 500
- Engine90V8.torque = 575 --in Meter/Kg
- Engine90V8.flywheelmass = 0.25
-
- Engine90V8.idlerpm = 700 --in Rotations Per Minute
- Engine90V8.peakminrpm = 3100
- Engine90V8.peakmaxrpm = 5000
- Engine90V8.limitprm = 5500
- if ( CLIENT ) then
- Engine90V8.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine90V8.guiupdate = function() return end
- end
-MobilityTable["9.0-V8"] = Engine90V8
-
-local Engine57V8 = {}
- Engine57V8.id = "5.7-V8"
- Engine57V8.ent = "acf_engine"
- Engine57V8.type = "Mobility"
- Engine57V8.name = "5.7L V8 Petrol"
- Engine57V8.desc = "Car sized petrol engine, good power and mid range torque"
- Engine57V8.model = "models/engines/v8s.mdl"
- Engine57V8.sound = "ACF_engines/v8_petrolsmall.wav"
- Engine57V8.category = "V8"
- Engine57V8.weight = 350
- Engine57V8.torque = 400 --in Meter/Kg
- Engine57V8.flywheelmass = 0.15
- --Engine57V8.idlesound = "ACF_engines/v8idle_petrolsmall.wav"
-
- Engine57V8.idlerpm = 800 --in Rotations Per Minute
- Engine57V8.peakminrpm = 3000
- Engine57V8.peakmaxrpm = 5000
- Engine57V8.limitprm = 6500
- if ( CLIENT ) then
- Engine57V8.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine57V8.guiupdate = function() return end
- end
-MobilityTable["5.7-V8"] = Engine57V8
-
-
-
-
---Diesel V8s
-local Engine190V8 = {}
- Engine190V8.id = "19.0-V8"
- Engine190V8.ent = "acf_engine"
- Engine190V8.type = "Mobility"
- Engine190V8.name = "19.0L V8 Diesel"
- Engine190V8.desc = "Heavy duty diesel V8, used for heavy construction equipment"
- Engine190V8.model = "models/engines/v8l.mdl"
- Engine190V8.sound = "ACF_engines/v8_diesellarge.wav"
- Engine190V8.category = "V8"
- Engine190V8.weight = 1300
- Engine190V8.torque = 2400 --in Meter/Kg
- Engine190V8.flywheelmass = 4.5
-
- Engine190V8.idlerpm = 500 --in Rotations Per Minute
- Engine190V8.peakminrpm = 550
- Engine190V8.peakmaxrpm = 1650
- Engine190V8.limitprm = 2700
- if ( CLIENT ) then
- Engine190V8.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine190V8.guiupdate = function() return end
- end
-MobilityTable["19.0-V8"] = Engine190V8
-
-local Engine78V8 = {}
- Engine78V8.id = "7.8-V8"
- Engine78V8.ent = "acf_engine"
- Engine78V8.type = "Mobility"
- Engine78V8.name = "7.8L V8 Diesel"
- Engine78V8.desc = "Utility grade V8 diesel, has a good, wide powerband"
- Engine78V8.model = "models/engines/v8m.mdl"
- Engine78V8.sound = "ACF_engines/v8_dieselmedium2.wav"
- Engine78V8.category = "V8"
- Engine78V8.weight = 600
- Engine78V8.torque = 710 --in Meter/Kg
- Engine78V8.flywheelmass = 1.5
-
- Engine78V8.idlerpm = 650 --in Rotations Per Minute
- Engine78V8.peakminrpm = 1000
- Engine78V8.peakmaxrpm = 3000
- Engine78V8.limitprm = 4000
- if ( CLIENT ) then
- Engine78V8.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine78V8.guiupdate = function() return end
- end
-MobilityTable["7.8-V8"] = Engine78V8
-
-local Engine45V8 = {}
- Engine45V8.id = "4.5-V8"
- Engine45V8.ent = "acf_engine"
- Engine45V8.type = "Mobility"
- Engine45V8.name = "4.5L V8 Diesel"
- Engine45V8.desc = "Light duty diesel v8, good for light vehicles that require a lot of torque"
- Engine45V8.model = "models/engines/v8s.mdl"
- Engine45V8.sound = "ACF_engines/v8_dieselsmall.wav"
- Engine45V8.category = "V8"
- Engine45V8.weight = 400
- Engine45V8.torque = 475 --in Meter/Kg
- Engine45V8.flywheelmass = 0.75
-
- Engine45V8.idlerpm = 800 --in Rotations Per Minute
- Engine45V8.peakminrpm = 1000
- Engine45V8.peakmaxrpm = 3000
- Engine45V8.limitprm = 5000
- if ( CLIENT ) then
- Engine45V8.guicreate = (function( Panel, Table ) ACFEngineGUICreate( Table ) end or nil)
- Engine45V8.guiupdate = function() return end
- end
-MobilityTable["4.5-V8"] = Engine45V8
-
-
-
-
-
--- Diffs
-
-local Gear1TS = {}
- Gear1TS.id = "1Gear-T-S"
- Gear1TS.ent = "acf_gearbox"
- Gear1TS.type = "Mobility"
- Gear1TS.name = "Differential, Small"
- Gear1TS.desc = "Small differential, used to connect power from gearbox to wheels"
- Gear1TS.model = "models/engines/transaxial_s.mdl"
- Gear1TS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TS.category = "Differential"
- Gear1TS.weight = Gear1SW
- Gear1TS.switch = 0.3
- Gear1TS.maxtq = GearTDSMT
- Gear1TS.gears = 1
- Gear1TS.doubleclutch = false
- Gear1TS.geartable = {}
- Gear1TS.geartable[-1] = 0.5
- Gear1TS.geartable[0] = 0
- Gear1TS.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TS.guiupdate = function() return end
- end
-MobilityTable["1Gear-T-S"] = Gear1TS
-
-local Gear1TM = {}
- Gear1TM.id = "1Gear-T-M"
- Gear1TM.ent = "acf_gearbox"
- Gear1TM.type = "Mobility"
- Gear1TM.name = "Differential, Medium"
- Gear1TM.desc = "Medium duty differential"
- Gear1TM.model = "models/engines/transaxial_m.mdl"
- Gear1TM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TM.category = "Differential"
- Gear1TM.weight = Gear1MW
- Gear1TM.switch = 0.4
- Gear1TM.maxtq = GearMMT
- Gear1TM.gears = 1
- Gear1TM.doubleclutch = false
- Gear1TM.geartable = {}
- Gear1TM.geartable[-1] = 0.5
- Gear1TM.geartable[0] = 0
- Gear1TM.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TM.guiupdate = function() return end
- end
-MobilityTable["1Gear-T-M"] = Gear1TM
-
-local Gear1TL = {}
- Gear1TL.id = "1Gear-T-L"
- Gear1TL.ent = "acf_gearbox"
- Gear1TL.type = "Mobility"
- Gear1TL.name = "Differential, Large"
- Gear1TL.desc = "Heavy duty differential, for the heaviest of engines"
- Gear1TL.model = "models/engines/transaxial_l.mdl"
- Gear1TL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TL.category = "Differential"
- Gear1TL.weight = Gear1LW
- Gear1TL.switch = 0.6
- Gear1TL.maxtq = GearLMT
- Gear1TL.gears = 1
- Gear1TL.doubleclutch = false
- Gear1TL.geartable = {}
- Gear1TL.geartable[-1] = 1
- Gear1TL.geartable[0] = 0
- Gear1TL.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TL.guiupdate = function() return end
- end
-MobilityTable["1Gear-T-L"] = Gear1TL
-
-
-
-local Gear1LS = {}
- Gear1LS.id = "1Gear-L-S"
- Gear1LS.ent = "acf_gearbox"
- Gear1LS.type = "Mobility"
- Gear1LS.name = "Differential, Inline, Small"
- Gear1LS.desc = "Small differential, used to connect power from gearbox to wheels"
- Gear1LS.model = "models/engines/linear_s.mdl"
- Gear1LS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LS.category = "Differential"
- Gear1LS.weight = Gear1SW
- Gear1LS.switch = 0.3
- Gear1LS.maxtq = GearTDSMT
- Gear1LS.gears = 1
- Gear1LS.doubleclutch = false
- Gear1LS.geartable = {}
- Gear1LS.geartable[-1] = 0.5
- Gear1LS.geartable[0] = 0
- Gear1LS.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LS.guiupdate = function() return end
- end
-MobilityTable["1Gear-L-S"] = Gear1LS
-
-local Gear1LM = {}
- Gear1LM.id = "1Gear-L-M"
- Gear1LM.ent = "acf_gearbox"
- Gear1LM.type = "Mobility"
- Gear1LM.name = "Differential, Inline, Medium"
- Gear1LM.desc = "Medium duty differential"
- Gear1LM.model = "models/engines/linear_m.mdl"
- Gear1LM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LM.category = "Differential"
- Gear1LM.weight = Gear1MW
- Gear1LM.switch = 0.4
- Gear1LM.maxtq = GearMMT
- Gear1LM.gears = 1
- Gear1LM.doubleclutch = false
- Gear1LM.geartable = {}
- Gear1LM.geartable[-1] = 0.5
- Gear1LM.geartable[0] = 0
- Gear1LM.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LM.guiupdate = function() return end
- end
-MobilityTable["1Gear-L-M"] = Gear1LM
-
-local Gear1LL = {}
- Gear1LL.id = "1Gear-L-L"
- Gear1LL.ent = "acf_gearbox"
- Gear1LL.type = "Mobility"
- Gear1LL.name = "Differential, Inline, Large"
- Gear1LL.desc = "Heavy duty differential, for the heaviest of engines"
- Gear1LL.model = "models/engines/linear_l.mdl"
- Gear1LL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LL.category = "Differential"
- Gear1LL.weight = Gear1LW
- Gear1LL.switch = 0.6
- Gear1LL.maxtq = GearLMT
- Gear1LL.gears = 1
- Gear1LL.doubleclutch = false
- Gear1LL.geartable = {}
- Gear1LL.geartable[-1] = 1
- Gear1LL.geartable[0] = 0
- Gear1LL.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LL.guiupdate = function() return end
- end
-MobilityTable["1Gear-L-L"] = Gear1LL
-
---Diffs, dual clutch
-
-
-local Gear1TDS = {}
- Gear1TDS.id = "1Gear-TD-S"
- Gear1TDS.ent = "acf_gearbox"
- Gear1TDS.type = "Mobility"
- Gear1TDS.name = "Differential, Small, Dual Clutch"
- Gear1TDS.desc = "Small differential, used to connect power from gearbox to wheels"
- Gear1TDS.model = "models/engines/transaxial_s.mdl"
- Gear1TDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TDS.category = "Differential"
- Gear1TDS.weight = Gear1SW
- Gear1TDS.switch = 0.3
- Gear1TDS.maxtq = GearTDSMT
- Gear1TDS.gears = 1
- Gear1TDS.doubleclutch = true
- Gear1TDS.geartable = {}
- Gear1TDS.geartable[-1] = 0.5
- Gear1TDS.geartable[0] = 0
- Gear1TDS.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TDS.guiupdate = function() return end
- end
-MobilityTable["1Gear-TD-S"] = Gear1TDS
-
-local Gear1TDM = {}
- Gear1TDM.id = "1Gear-TD-M"
- Gear1TDM.ent = "acf_gearbox"
- Gear1TDM.type = "Mobility"
- Gear1TDM.name = "Differential, Medium, Dual Clutch"
- Gear1TDM.desc = "Medium duty differential"
- Gear1TDM.model = "models/engines/transaxial_m.mdl"
- Gear1TDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TDM.category = "Differential"
- Gear1TDM.weight = Gear1MW
- Gear1TDM.switch = 0.4
- Gear1TDM.maxtq = GearMMT
- Gear1TDM.gears = 1
- Gear1TDM.doubleclutch = true
- Gear1TDM.geartable = {}
- Gear1TDM.geartable[-1] = 0.5
- Gear1TDM.geartable[0] = 0
- Gear1TDM.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TDM.guiupdate = function() return end
- end
-MobilityTable["1Gear-TD-M"] = Gear1TDM
-
-local Gear1TDL = {}
- Gear1TDL.id = "1Gear-TD-L"
- Gear1TDL.ent = "acf_gearbox"
- Gear1TDL.type = "Mobility"
- Gear1TDL.name = "Differential, Large, Dual Clutch"
- Gear1TDL.desc = "Heavy duty differential, for the heaviest of engines"
- Gear1TDL.model = "models/engines/transaxial_l.mdl"
- Gear1TDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TDL.category = "Differential"
- Gear1TDL.weight = Gear1LW
- Gear1TDL.switch = 0.6
- Gear1TDL.maxtq = GearLMT
- Gear1TDL.gears = 1
- Gear1TDL.doubleclutch = true
- Gear1TDL.geartable = {}
- Gear1TDL.geartable[-1] = 1
- Gear1TDL.geartable[0] = 0
- Gear1TDL.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TDL.guiupdate = function() return end
- end
-MobilityTable["1Gear-TD-L"] = Gear1TDL
-
-
-
-local Gear1LDS = {}
- Gear1LDS.id = "1Gear-LD-S"
- Gear1LDS.ent = "acf_gearbox"
- Gear1LDS.type = "Mobility"
- Gear1LDS.name = "Differential, Inline, Small, Dual Clutch"
- Gear1LDS.desc = "Small differential, used to connect power from gearbox to wheels"
- Gear1LDS.model = "models/engines/linear_s.mdl"
- Gear1LDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LDS.category = "Differential"
- Gear1LDS.weight = Gear1SW
- Gear1LDS.switch = 0.3
- Gear1LDS.maxtq = GearTDSMT
- Gear1LDS.gears = 1
- Gear1LDS.doubleclutch = true
- Gear1LDS.geartable = {}
- Gear1LDS.geartable[-1] = 0.5
- Gear1LDS.geartable[0] = 0
- Gear1LDS.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LDS.guiupdate = function() return end
- end
-MobilityTable["1Gear-LD-S"] = Gear1LDS
-
-local Gear1LDM = {}
- Gear1LDM.id = "1Gear-LD-M"
- Gear1LDM.ent = "acf_gearbox"
- Gear1LDM.type = "Mobility"
- Gear1LDM.name = "Differential, Inline, Medium, Dual Clutch"
- Gear1LDM.desc = "Medium duty differential"
- Gear1LDM.model = "models/engines/linear_m.mdl"
- Gear1LDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LDM.category = "Differential"
- Gear1LDM.weight = Gear1MW
- Gear1LDM.switch = 0.4
- Gear1LDM.maxtq = GearMMT
- Gear1LDM.gears = 1
- Gear1LDM.doubleclutch = true
- Gear1LDM.geartable = {}
- Gear1LDM.geartable[-1] = 0.5
- Gear1LDM.geartable[0] = 0
- Gear1LDM.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LDM.guiupdate = function() return end
- end
-MobilityTable["1Gear-LD-M"] = Gear1LDM
-
-local Gear1LDL = {}
- Gear1LDL.id = "1Gear-LD-L"
- Gear1LDL.ent = "acf_gearbox"
- Gear1LDL.type = "Mobility"
- Gear1LDL.name = "Differential, Inline, Large, Dual Clutch"
- Gear1LDL.desc = "Heavy duty differential, for the heaviest of engines"
- Gear1LDL.model = "models/engines/linear_l.mdl"
- Gear1LDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LDL.category = "Differential"
- Gear1LDL.weight = Gear1LW
- Gear1LDL.switch = 0.6
- Gear1LDL.maxtq = GearLMT
- Gear1LDL.gears = 1
- Gear1LDL.doubleclutch = true
- Gear1LDL.geartable = {}
- Gear1LDL.geartable[-1] = 1
- Gear1LDL.geartable[0] = 0
- Gear1LDL.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LDL.guiupdate = function() return end
- end
-MobilityTable["1Gear-LD-L"] = Gear1LDL
-
-
---2 speed transfer boxes
-
-local Gear2TS = {}
- Gear2TS.id = "2Gear-T-S"
- Gear2TS.ent = "acf_gearbox"
- Gear2TS.type = "Mobility"
- Gear2TS.name = "Transfer case, Small"
- Gear2TS.desc = "2 speed gearbox, useful for low/high range and tank turning"
- Gear2TS.model = "models/engines/transaxial_s.mdl"
- Gear2TS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear2TS.category = "Transfer"
- Gear2TS.weight = Gear2SW
- Gear2TS.switch = 0.3
- Gear2TS.maxtq = GearTDSMT
- Gear2TS.gears = 2
- Gear2TS.doubleclutch = true
- Gear2TS.geartable = {}
- Gear2TS.geartable[-1] = 0.5
- Gear2TS.geartable[0] = 0
- Gear2TS.geartable[1] = 0.5
- Gear2TS.geartable[2] = -0.5
- if ( CLIENT ) then
- Gear2TS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear2TS.guiupdate = function() return end
- end
-MobilityTable["2Gear-T-S"] = Gear2TS
-
-local Gear2TM = {}
- Gear2TM.id = "2Gear-T-M"
- Gear2TM.ent = "acf_gearbox"
- Gear2TM.type = "Mobility"
- Gear2TM.name = "Transfer case, Medium"
- Gear2TM.desc = "2 speed gearbox, useful for low/high range and tank turning"
- Gear2TM.model = "models/engines/transaxial_m.mdl"
- Gear2TM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear2TM.category = "Transfer"
- Gear2TM.weight = Gear2MW
- Gear2TM.switch = 0.4
- Gear2TM.maxtq = GearMMT
- Gear2TM.gears = 2
- Gear2TM.doubleclutch = true
- Gear2TM.geartable = {}
- Gear2TM.geartable[-1] = 0.5
- Gear2TM.geartable[0] = 0
- Gear2TM.geartable[1] = 0.5
- Gear2TM.geartable[2] = -0.5
- if ( CLIENT ) then
- Gear2TM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear2TM.guiupdate = function() return end
- end
-MobilityTable["2Gear-T-M"] = Gear2TM
-
-local Gear2TL = {}
- Gear2TL.id = "2Gear-T-L"
- Gear2TL.ent = "acf_gearbox"
- Gear2TL.type = "Mobility"
- Gear2TL.name = "Transfer case, Large"
- Gear2TL.desc = "2 speed gearbox, useful for low/high range and tank turning"
- Gear2TL.model = "models/engines/transaxial_l.mdl"
- Gear2TL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear2TL.category = "Transfer"
- Gear2TL.weight = Gear2LW
- Gear2TL.switch = 0.6
- Gear2TL.maxtq = GearLMT
- Gear2TL.gears = 2
- Gear2TL.doubleclutch = true
- Gear2TL.geartable = {}
- Gear2TL.geartable[-1] = 1
- Gear2TL.geartable[0] = 0
- Gear2TL.geartable[1] = 0.5
- Gear2TL.geartable[2] = -0.5
- if ( CLIENT ) then
- Gear2TL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear2TL.guiupdate = function() return end
- end
-MobilityTable["2Gear-T-L"] = Gear2TL
-
-local Gear2LS = {}
- Gear2LS.id = "2Gear-L-S"
- Gear2LS.ent = "acf_gearbox"
- Gear2LS.type = "Mobility"
- Gear2LS.name = "Transfer case, Inline, Small"
- Gear2LS.desc = "2 speed gearbox, useful for low/high range and tank turning"
- Gear2LS.model = "models/engines/linear_s.mdl"
- Gear2LS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear2LS.category = "Transfer"
- Gear2LS.weight = Gear2SW
- Gear2LS.switch = 0.3
- Gear2LS.maxtq = GearTDSMT
- Gear2LS.gears = 2
- Gear2LS.doubleclutch = true
- Gear2LS.geartable = {}
- Gear2LS.geartable[-1] = 0.5
- Gear2LS.geartable[0] = 0
- Gear2LS.geartable[1] = 0.5
- Gear2LS.geartable[2] = -0.5
- if ( CLIENT ) then
- Gear2LS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear2LS.guiupdate = function() return end
- end
-MobilityTable["2Gear-L-S"] = Gear2LS
-
-local Gear2LM = {}
- Gear2LM.id = "2Gear-L-M"
- Gear2LM.ent = "acf_gearbox"
- Gear2LM.type = "Mobility"
- Gear2LM.name = "Transfer case, Inline, Medium"
- Gear2LM.desc = "2 speed gearbox, useful for low/high range and tank turning"
- Gear2LM.model = "models/engines/linear_m.mdl"
- Gear2LM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear2LM.category = "Transfer"
- Gear2LM.weight = Gear2MW
- Gear2LM.switch = 0.4
- Gear2LM.maxtq = GearMMT
- Gear2LM.gears = 2
- Gear2LM.doubleclutch = true
- Gear2LM.geartable = {}
- Gear2LM.geartable[-1] = 0.5
- Gear2LM.geartable[0] = 0
- Gear2LM.geartable[1] = 0.5
- Gear2LM.geartable[2] = -0.5
- if ( CLIENT ) then
- Gear2LM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear2LM.guiupdate = function() return end
- end
-MobilityTable["2Gear-L-M"] = Gear2LM
-
-local Gear2LL = {}
- Gear2LL.id = "2Gear-L-L"
- Gear2LL.ent = "acf_gearbox"
- Gear2LL.type = "Mobility"
- Gear2LL.name = "Transfer case, Inline, Large"
- Gear2LL.desc = "2 speed gearbox, useful for low/high range and tank turning"
- Gear2LL.model = "models/engines/linear_l.mdl"
- Gear2LL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear2LL.category = "Transfer"
- Gear2LL.weight = Gear2LW
- Gear2LL.switch = 0.6
- Gear2LL.maxtq = GearLMT
- Gear2LL.gears = 2
- Gear2LL.doubleclutch = true
- Gear2LL.geartable = {}
- Gear2LL.geartable[-1] = 1
- Gear2LL.geartable[0] = 0
- Gear2LL.geartable[1] = 0.5
- Gear2LL.geartable[2] = -0.5
- if ( CLIENT ) then
- Gear2LL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear2LL.guiupdate = function() return end
- end
-MobilityTable["2Gear-L-L"] = Gear2LL
-
-
-
-local Gear1LS = {}
- Gear1LS.id = "1Gear-L-S"
- Gear1LS.ent = "acf_gearbox"
- Gear1LS.type = "Mobility"
- Gear1LS.name = "Differential, Inline, Small"
- Gear1LS.desc = "Small differential, used to connect power from gearbox to wheels"
- Gear1LS.model = "models/engines/linear_s.mdl"
- Gear1LS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LS.category = "Differential"
- Gear1LS.weight = Gear1SW
- Gear1LS.switch = 0.3
- Gear1LS.maxtq = GearTDSMT
- Gear1LS.gears = 1
- Gear1LS.doubleclutch = false
- Gear1LS.geartable = {}
- Gear1LS.geartable[-1] = 0.5
- Gear1LS.geartable[0] = 0
- Gear1LS.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LS.guiupdate = function() return end
- end
-MobilityTable["1Gear-L-S"] = Gear1LS
-
-local Gear1LM = {}
- Gear1LM.id = "1Gear-L-M"
- Gear1LM.ent = "acf_gearbox"
- Gear1LM.type = "Mobility"
- Gear1LM.name = "Differential, Inline, Medium"
- Gear1LM.desc = "Medium duty differential"
- Gear1LM.model = "models/engines/linear_m.mdl"
- Gear1LM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LM.category = "Differential"
- Gear1LM.weight = Gear1MW
- Gear1LM.switch = 0.4
- Gear1LM.maxtq = GearMMT
- Gear1LM.gears = 1
- Gear1LM.doubleclutch = false
- Gear1LM.geartable = {}
- Gear1LM.geartable[-1] = 0.5
- Gear1LM.geartable[0] = 0
- Gear1LM.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LM.guiupdate = function() return end
- end
-MobilityTable["1Gear-L-M"] = Gear1LM
-
-local Gear1LL = {}
- Gear1LL.id = "1Gear-L-L"
- Gear1LL.ent = "acf_gearbox"
- Gear1LL.type = "Mobility"
- Gear1LL.name = "Differential, Inline, Large"
- Gear1LL.desc = "Heavy duty differential, for the heaviest of engines"
- Gear1LL.model = "models/engines/linear_l.mdl"
- Gear1LL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LL.category = "Differential"
- Gear1LL.weight = Gear1LW
- Gear1LL.switch = 0.6
- Gear1LL.maxtq = GearLMT
- Gear1LL.gears = 1
- Gear1LL.doubleclutch = false
- Gear1LL.geartable = {}
- Gear1LL.geartable[-1] = 1
- Gear1LL.geartable[0] = 0
- Gear1LL.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LL.guiupdate = function() return end
- end
-MobilityTable["1Gear-L-L"] = Gear1LL
-
---
-
-
-local Gear1TDS = {}
- Gear1TDS.id = "1Gear-TD-S"
- Gear1TDS.ent = "acf_gearbox"
- Gear1TDS.type = "Mobility"
- Gear1TDS.name = "Differential, Small, Dual Clutch"
- Gear1TDS.desc = "Small differential, used to connect power from gearbox to wheels"
- Gear1TDS.model = "models/engines/transaxial_s.mdl"
- Gear1TDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TDS.category = "Differential"
- Gear1TDS.weight = Gear1SW
- Gear1TDS.switch = 0.3
- Gear1TDS.maxtq = GearTDSMT
- Gear1TDS.gears = 1
- Gear1TDS.doubleclutch = true
- Gear1TDS.geartable = {}
- Gear1TDS.geartable[-1] = 0.5
- Gear1TDS.geartable[0] = 0
- Gear1TDS.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TDS.guiupdate = function() return end
- end
-MobilityTable["1Gear-TD-S"] = Gear1TDS
-
-local Gear1TDM = {}
- Gear1TDM.id = "1Gear-TD-M"
- Gear1TDM.ent = "acf_gearbox"
- Gear1TDM.type = "Mobility"
- Gear1TDM.name = "Differential, Medium, Dual Clutch"
- Gear1TDM.desc = "Medium duty differential"
- Gear1TDM.model = "models/engines/transaxial_m.mdl"
- Gear1TDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TDM.category = "Differential"
- Gear1TDM.weight = Gear1MW
- Gear1TDM.switch = 0.4
- Gear1TDM.maxtq = GearMMT
- Gear1TDM.gears = 1
- Gear1TDM.doubleclutch = true
- Gear1TDM.geartable = {}
- Gear1TDM.geartable[-1] = 0.5
- Gear1TDM.geartable[0] = 0
- Gear1TDM.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TDM.guiupdate = function() return end
- end
-MobilityTable["1Gear-TD-M"] = Gear1DTM
-
-local Gear1TDL = {}
- Gear1TDL.id = "1Gear-TD-L"
- Gear1TDL.ent = "acf_gearbox"
- Gear1TDL.type = "Mobility"
- Gear1TDL.name = "Differential, Large, Dual Clutch"
- Gear1TDL.desc = "Heavy duty differential, for the heaviest of engines"
- Gear1TDL.model = "models/engines/transaxial_l.mdl"
- Gear1TDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1TDL.category = "Differential"
- Gear1TDL.weight = Gear1LW
- Gear1TDL.switch = 0.6
- Gear1TDL.maxtq = GearLMT
- Gear1TDL.gears = 1
- Gear1TDL.doubleclutch = true
- Gear1TDL.geartable = {}
- Gear1TDL.geartable[-1] = 1
- Gear1TDL.geartable[0] = 0
- Gear1TDL.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1TDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1TDL.guiupdate = function() return end
- end
-MobilityTable["1Gear-TD-L"] = Gear1TDL
-
-
-
-local Gear1LDS = {}
- Gear1LDS.id = "1Gear-LD-S"
- Gear1LDS.ent = "acf_gearbox"
- Gear1LDS.type = "Mobility"
- Gear1LDS.name = "Differential, Inline, Small, Dual Clutch"
- Gear1LDS.desc = "Small differential, used to connect power from gearbox to wheels"
- Gear1LDS.model = "models/engines/linear_s.mdl"
- Gear1LDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LDS.category = "Differential"
- Gear1LDS.weight = Gear1SW
- Gear1LDS.switch = 0.3
- Gear1LDS.maxtq = GearTDSMT
- Gear1LDS.gears = 1
- Gear1LDS.doubleclutch = true
- Gear1LDS.geartable = {}
- Gear1LDS.geartable[-1] = 0.5
- Gear1LDS.geartable[0] = 0
- Gear1LDS.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LDS.guiupdate = function() return end
- end
-MobilityTable["1Gear-LD-S"] = Gear1LDS
-
-local Gear1LDM = {}
- Gear1LDM.id = "1Gear-LD-M"
- Gear1LDM.ent = "acf_gearbox"
- Gear1LDM.type = "Mobility"
- Gear1LDM.name = "Differential, Inline, Medium, Dual Clutch"
- Gear1LDM.desc = "Medium duty differential"
- Gear1LDM.model = "models/engines/linear_m.mdl"
- Gear1LDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LDM.category = "Differential"
- Gear1LDM.weight = Gear1MW
- Gear1LDM.switch = 0.4
- Gear1LDM.maxtq = GearMMT
- Gear1LDM.gears = 1
- Gear1LDM.doubleclutch = true
- Gear1LDM.geartable = {}
- Gear1LDM.geartable[-1] = 0.5
- Gear1LDM.geartable[0] = 0
- Gear1LDM.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LDM.guiupdate = function() return end
- end
-MobilityTable["1Gear-LD-M"] = Gear1LDM
-
-local Gear1LDL = {}
- Gear1LDL.id = "1Gear-LD-L"
- Gear1LDL.ent = "acf_gearbox"
- Gear1LDL.type = "Mobility"
- Gear1LDL.name = "Differential, Inline, Large, Dual Clutch"
- Gear1LDL.desc = "Heavy duty differential, for the heaviest of engines"
- Gear1LDL.model = "models/engines/linear_l.mdl"
- Gear1LDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear1LDL.category = "Differential"
- Gear1LDL.weight = Gear1LW
- Gear1LDL.switch = 0.6
- Gear1LDL.maxtq = GearLMT
- Gear1LDL.gears = 1
- Gear1LDL.doubleclutch = true
- Gear1LDL.geartable = {}
- Gear1LDL.geartable[-1] = 1
- Gear1LDL.geartable[0] = 0
- Gear1LDL.geartable[1] = 0.5
- if ( CLIENT ) then
- Gear1LDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear1LDL.guiupdate = function() return end
- end
-MobilityTable["1Gear-LD-L"] = Gear1LDL
-
--- 4 speed normal gearboxes
-local Gear4TS = {}
- Gear4TS.id = "4Gear-T-S"
- Gear4TS.ent = "acf_gearbox"
- Gear4TS.type = "Mobility"
- Gear4TS.name = "4-Speed, Transaxial, Small"
- Gear4TS.desc = "A small, and light 4 speed gearbox, with a somewhat limited max torque rating\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear4TS.model = "models/engines/transaxial_s.mdl"
- Gear4TS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TS.category = "4-Speed"
- Gear4TS.weight = Gear4SW
- Gear4TS.switch = 0.3
- Gear4TS.maxtq = GearSMT
- Gear4TS.gears = 4
- Gear4TS.doubleclutch = false
- Gear4TS.geartable = {}
- Gear4TS.geartable[-1] = 0.5
- Gear4TS.geartable[0] = 0
- Gear4TS.geartable[1] = 0.1
- Gear4TS.geartable[2] = 0.2
- Gear4TS.geartable[3] = 0.3
- Gear4TS.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TS.guiupdate = function() return end
- end
-MobilityTable["4Gear-T-S"] = Gear4TS
-
-local Gear4TM = {}
- Gear4TM.id = "4Gear-T-M"
- Gear4TM.ent = "acf_gearbox"
- Gear4TM.type = "Mobility"
- Gear4TM.name = "4-Speed, Transaxial, Medium"
- Gear4TM.desc = "A medium sized, 4 speed gearbox"
- Gear4TM.model = "models/engines/transaxial_m.mdl"
- Gear4TM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TM.category = "4-Speed"
- Gear4TM.weight = Gear4MW
- Gear4TM.switch = 0.4
- Gear4TM.maxtq = GearMMT
- Gear4TM.gears = 4
- Gear4TM.doubleclutch = false
- Gear4TM.geartable = {}
- Gear4TM.geartable[-1] = 0.5
- Gear4TM.geartable[0] = 0
- Gear4TM.geartable[1] = 0.1
- Gear4TM.geartable[2] = 0.2
- Gear4TM.geartable[3] = 0.3
- Gear4TM.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TM.guiupdate = function() return end
- end
-MobilityTable["4Gear-T-M"] = Gear4TM
-
-local Gear4TL = {}
- Gear4TL.id = "4Gear-T-L"
- Gear4TL.ent = "acf_gearbox"
- Gear4TL.type = "Mobility"
- Gear4TL.name = "4-Speed, Transaxial, Large"
- Gear4TL.desc = "A large, heavy and sturdy 4 speed gearbox"
- Gear4TL.model = "models/engines/transaxial_l.mdl"
- Gear4TL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TL.category = "4-Speed"
- Gear4TL.weight = Gear4LW
- Gear4TL.switch = 0.6
- Gear4TL.maxtq = GearLMT
- Gear4TL.gears = 4
- Gear4TL.doubleclutch = false
- Gear4TL.geartable = {}
- Gear4TL.geartable[-1] = 1
- Gear4TL.geartable[0] = 0
- Gear4TL.geartable[1] = 0.1
- Gear4TL.geartable[2] = 0.2
- Gear4TL.geartable[3] = 0.3
- Gear4TL.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TL.guiupdate = function() return end
- end
-MobilityTable["4Gear-T-L"] = Gear4TL
-
-
-
-
--- 4 speed dual clutch gearboxes
-local Gear4TDS = {}
- Gear4TDS.id = "4Gear-TD-S"
- Gear4TDS.ent = "acf_gearbox"
- Gear4TDS.type = "Mobility"
- Gear4TDS.name = "4-Speed, Transaxial Dual Clutch, Small"
- Gear4TDS.desc = "A small, and light 4 speed gearbox, with a somewhat limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear4TDS.model = "models/engines/transaxial_s.mdl"
- Gear4TDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TDS.category = "4-Speed"
- Gear4TDS.weight = Gear4SW
- Gear4TDS.switch = 0.3
- Gear4TDS.maxtq = GearSMT
- Gear4TDS.gears = 4
- Gear4TDS.doubleclutch = true
- Gear4TDS.geartable = {}
- Gear4TDS.geartable[-1] = 0.5
- Gear4TDS.geartable[0] = 0
- Gear4TDS.geartable[1] = 0.1
- Gear4TDS.geartable[2] = 0.2
- Gear4TDS.geartable[3] = 0.3
- Gear4TDS.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TDS.guiupdate = function() return end
- end
-MobilityTable["4Gear-TD-S"] = Gear4TDS
-
-local Gear4TDM = {}
- Gear4TDM.id = "4Gear-TD-M"
- Gear4TDM.ent = "acf_gearbox"
- Gear4TDM.type = "Mobility"
- Gear4TDM.name = "4-Speed, Transaxial Dual Clutch, Medium"
- Gear4TDM.desc = "A medium sized, 4 speed gearbox. The dual clutch allows you to apply power and brake each side independently"
- Gear4TDM.model = "models/engines/transaxial_m.mdl"
- Gear4TDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TDM.category = "4-Speed"
- Gear4TDM.weight = Gear4MW
- Gear4TDM.switch = 0.4
- Gear4TDM.maxtq = GearMMT
- Gear4TDM.gears = 4
- Gear4TDM.doubleclutch = true
- Gear4TDM.geartable = {}
- Gear4TDM.geartable[-1] = 0.5
- Gear4TDM.geartable[0] = 0
- Gear4TDM.geartable[1] = 0.1
- Gear4TDM.geartable[2] = 0.2
- Gear4TDM.geartable[3] = 0.3
- Gear4TDM.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TDM.guiupdate = function() return end
- end
-MobilityTable["4Gear-TD-M"] = Gear4TDM
-
-local Gear4TDL = {}
- Gear4TDL.id = "4Gear-TD-L"
- Gear4TDL.ent = "acf_gearbox"
- Gear4TDL.type = "Mobility"
- Gear4TDL.name = "4-Speed, Transaxial Dual Clutch, Large"
- Gear4TDL.desc = "A large, heavy and sturdy 4 speed gearbox. The dual clutch allows you to apply power and brake each side independently"
- Gear4TDL.model = "models/engines/transaxial_l.mdl"
- Gear4TDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TDL.category = "4-Speed"
- Gear4TDL.weight = Gear4LW
- Gear4TDL.switch = 0.6
- Gear4TDL.maxtq = GearLMT
- Gear4TDL.gears = 4
- Gear4TDL.doubleclutch = true
- Gear4TDL.geartable = {}
- Gear4TDL.geartable[-1] = 1
- Gear4TDL.geartable[0] = 0
- Gear4TDL.geartable[1] = 0.1
- Gear4TDL.geartable[2] = 0.2
- Gear4TDL.geartable[3] = 0.3
- Gear4TDL.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TDL.guiupdate = function() return end
- end
-MobilityTable["4Gear-TD-L"] = Gear4TDL
-
-
-
-
--- 6 speed normal gearboxes
-local Gear6TS = {}
- Gear6TS.id = "6Gear-T-S"
- Gear6TS.ent = "acf_gearbox"
- Gear6TS.type = "Mobility"
- Gear6TS.name = "6-Speed, Transaxial, Small"
- Gear6TS.desc = "A small and light 6 speed gearbox, with a limited max torque rating."
- Gear6TS.model = "models/engines/transaxial_s.mdl"
- Gear6TS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6TS.category = "6-Speed"
- Gear6TS.weight = Gear6SW
- Gear6TS.switch = 0.3
- Gear6TS.maxtq = GearSMT
- Gear6TS.gears = 6
- Gear6TS.doubleclutch = false
- Gear6TS.geartable = {}
- Gear6TS.geartable[-1] = 0.5
- Gear6TS.geartable[0] = 0
- Gear6TS.geartable[1] = 0.1
- Gear6TS.geartable[2] = 0.2
- Gear6TS.geartable[3] = 0.3
- Gear6TS.geartable[4] = 0.4
- Gear6TS.geartable[5] = 0.5
- Gear6TS.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6TS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6TS.guiupdate = function() return end
- end
-MobilityTable["6Gear-T-S"] = Gear6TS
-
-local Gear6TM = {}
- Gear6TM.id = "6Gear-T-M"
- Gear6TM.ent = "acf_gearbox"
- Gear6TM.type = "Mobility"
- Gear6TM.name = "6-Speed, Transaxial, Medium"
- Gear6TM.desc = "A medium duty 6 speed gearbox with a limited torque rating."
- Gear6TM.model = "models/engines/transaxial_m.mdl"
- Gear6TM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6TM.category = "6-Speed"
- Gear6TM.weight = Gear6MW
- Gear6TM.switch = 0.4
- Gear6TM.maxtq = GearMMT
- Gear6TM.gears = 6
- Gear6TM.doubleclutch = false
- Gear6TM.geartable = {}
- Gear6TM.geartable[-1] = 0.5
- Gear6TM.geartable[0] = 0
- Gear6TM.geartable[1] = 0.1
- Gear6TM.geartable[2] = 0.2
- Gear6TM.geartable[3] = 0.3
- Gear6TM.geartable[4] = 0.4
- Gear6TM.geartable[5] = 0.5
- Gear6TM.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6TM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6TM.guiupdate = function() return end
- end
-MobilityTable["6Gear-T-M"] = Gear6TM
-
-local Gear6TL = {}
- Gear6TL.id = "6Gear-T-L"
- Gear6TL.ent = "acf_gearbox"
- Gear6TL.type = "Mobility"
- Gear6TL.name = "6-Speed, Transaxial, Large"
- Gear6TL.desc = "Heavy duty 6 speed gearbox, however not as resilient as a 4 speed."
- Gear6TL.model = "models/engines/transaxial_l.mdl"
- Gear6TL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6TL.category = "6-Speed"
- Gear6TL.weight = Gear6LW
- Gear6TL.switch = 0.6
- Gear6TL.maxtq = GearLMT
- Gear6TL.gears = 6
- Gear6TL.doubleclutch = false
- Gear6TL.geartable = {}
- Gear6TL.geartable[-1] = 1
- Gear6TL.geartable[0] = 0
- Gear6TL.geartable[1] = 0.1
- Gear6TL.geartable[2] = 0.2
- Gear6TL.geartable[3] = 0.3
- Gear6TL.geartable[4] = 0.4
- Gear6TL.geartable[5] = 0.5
- Gear6TL.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6TL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6TL.guiupdate = function() return end
- end
-MobilityTable["6Gear-T-L"] = Gear6TL
-
-
-
-
--- 6 speed dual clutch gearboxes
-local Gear6TDS = {}
- Gear6TDS.id = "6Gear-TD-S"
- Gear6TDS.ent = "acf_gearbox"
- Gear6TDS.type = "Mobility"
- Gear6TDS.name = "6-Speed, Transaxial Dual Clutch, Small"
- Gear6TDS.desc = "A small and light 6 speed gearbox, with a limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6TDS.model = "models/engines/transaxial_s.mdl"
- Gear6TDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6TDS.category = "6-Speed"
- Gear6TDS.weight = Gear6SW
- Gear6TDS.switch = 0.3
- Gear6TDS.maxtq = GearSMT
- Gear6TDS.gears = 6
- Gear6TDS.doubleclutch = true
- Gear6TDS.geartable = {}
- Gear6TDS.geartable[-1] = 0.5
- Gear6TDS.geartable[0] = 0
- Gear6TDS.geartable[1] = 0.1
- Gear6TDS.geartable[2] = 0.2
- Gear6TDS.geartable[3] = 0.3
- Gear6TDS.geartable[4] = 0.4
- Gear6TDS.geartable[5] = 0.5
- Gear6TDS.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6TDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6TDS.guiupdate = function() return end
- end
-MobilityTable["6Gear-TD-S"] = Gear6TDS
-
-local Gear6TDM = {}
- Gear6TDM.id = "6Gear-TD-M"
- Gear6TDM.ent = "acf_gearbox"
- Gear6TDM.type = "Mobility"
- Gear6TDM.name = "6-Speed, Transaxial Dual Clutch, Medium"
- Gear6TDM.desc = "A a medium duty 6 speed gearbox. The added gears reduce torque capacity substantially. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6TDM.model = "models/engines/transaxial_m.mdl"
- Gear6TDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6TDM.category = "6-Speed"
- Gear6TDM.weight = Gear6MW
- Gear6TDM.switch = 0.4
- Gear6TDM.maxtq = GearMMT
- Gear6TDM.gears = 6
- Gear6TDM.doubleclutch = true
- Gear6TDM.geartable = {}
- Gear6TDM.geartable[-1] = 0.5
- Gear6TDM.geartable[0] = 0
- Gear6TDM.geartable[1] = 0.1
- Gear6TDM.geartable[2] = 0.2
- Gear6TDM.geartable[3] = 0.3
- Gear6TDM.geartable[4] = 0.4
- Gear6TDM.geartable[5] = 0.5
- Gear6TDM.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6TDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6TDM.guiupdate = function() return end
- end
-MobilityTable["6Gear-TD-M"] = Gear6TDM
-
-local Gear6TDL = {}
- Gear6TDL.id = "6Gear-TD-L"
- Gear6TDL.ent = "acf_gearbox"
- Gear6TDL.type = "Mobility"
- Gear6TDL.name = "6-Speed, Transaxial Dual Clutch, Large"
- Gear6TDL.desc = "Heavy duty 6 speed gearbox, however not as resilient as a 4 speed. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6TDL.model = "models/engines/transaxial_l.mdl"
- Gear6TDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6TDL.category = "6-Speed"
- Gear6TDL.weight = Gear6LW
- Gear6TDL.switch = 0.6
- Gear6TDL.maxtq = GearLMT
- Gear6TDL.gears = 6
- Gear6TDL.doubleclutch = true
- Gear6TDL.geartable = {}
- Gear6TDL.geartable[-1] = 1
- Gear6TDL.geartable[0] = 0
- Gear6TDL.geartable[1] = 0.1
- Gear6TDL.geartable[2] = 0.2
- Gear6TDL.geartable[3] = 0.3
- Gear6TDL.geartable[4] = 0.4
- Gear6TDL.geartable[5] = 0.5
- Gear6TDL.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6TDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6TDL.guiupdate = function() return end
- end
-MobilityTable["6Gear-TD-L"] = Gear6TDL
-
---8 speed gearboxes normal
-
-local Gear8TS = {}
- Gear8TS.id = "8Gear-T-S"
- Gear8TS.ent = "acf_gearbox"
- Gear8TS.type = "Mobility"
- Gear8TS.name = "8-Speed, Transaxial, Small"
- Gear8TS.desc = "A small and light 8 speed gearbox.."
- Gear8TS.model = "models/engines/transaxial_s.mdl"
- Gear8TS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8TS.category = "8-Speed"
- Gear8TS.weight = Gear8SW
- Gear8TS.switch = 0.3
- Gear8TS.maxtq = GearSMT
- Gear8TS.gears = 8
- Gear8TS.doubleclutch = false
- Gear8TS.geartable = {}
- Gear8TS.geartable[-1] = 0.5
- Gear8TS.geartable[0] = 0
- Gear8TS.geartable[1] = 0.1
- Gear8TS.geartable[2] = 0.2
- Gear8TS.geartable[3] = 0.3
- Gear8TS.geartable[4] = 0.4
- Gear8TS.geartable[5] = 0.5
- Gear8TS.geartable[6] = 0.6
- Gear8TS.geartable[7] = 0.7
- Gear8TS.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8TS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8TS.guiupdate = function() return end
- end
-MobilityTable["8Gear-T-S"] = Gear8TS
-
-local Gear8TM = {}
- Gear8TM.id = "8Gear-T-M"
- Gear8TM.ent = "acf_gearbox"
- Gear8TM.type = "Mobility"
- Gear8TM.name = "8-Speed, Transaxial, Medium"
- Gear8TM.desc = "A medium duty 8 speed gearbox.."
- Gear8TM.model = "models/engines/transaxial_m.mdl"
- Gear8TM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8TM.category = "8-Speed"
- Gear8TM.weight = Gear8MW
- Gear8TM.switch = 0.4
- Gear8TM.maxtq = GearMMT
- Gear8TM.gears = 8
- Gear8TM.doubleclutch = false
- Gear8TM.geartable = {}
- Gear8TM.geartable[-1] = 0.5
- Gear8TM.geartable[0] = 0
- Gear8TM.geartable[1] = 0.1
- Gear8TM.geartable[2] = 0.2
- Gear8TM.geartable[3] = 0.3
- Gear8TM.geartable[4] = 0.4
- Gear8TM.geartable[5] = 0.5
- Gear8TM.geartable[6] = 0.6
- Gear8TM.geartable[7] = 0.7
- Gear8TM.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8TM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8TM.guiupdate = function() return end
- end
-MobilityTable["8Gear-T-M"] = Gear8TM
-
-local Gear8TL = {}
- Gear8TL.id = "8Gear-T-L"
- Gear8TL.ent = "acf_gearbox"
- Gear8TL.type = "Mobility"
- Gear8TL.name = "8-Speed, Transaxial, Large"
- Gear8TL.desc = "Heavy duty 8 speed gearbox, however rather heavy."
- Gear8TL.model = "models/engines/transaxial_l.mdl"
- Gear8TL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8TL.category = "8-Speed"
- Gear8TL.weight = Gear8LW
- Gear8TL.switch = 0.6
- Gear8TL.maxtq = GearLMT
- Gear8TL.gears = 8
- Gear8TL.doubleclutch = false
- Gear8TL.geartable = {}
- Gear8TL.geartable[-1] = 1
- Gear8TL.geartable[0] = 0
- Gear8TL.geartable[1] = 0.1
- Gear8TL.geartable[2] = 0.2
- Gear8TL.geartable[3] = 0.3
- Gear8TL.geartable[4] = 0.4
- Gear8TL.geartable[5] = 0.5
- Gear8TL.geartable[6] = 0.6
- Gear8TL.geartable[7] = 0.7
- Gear8TL.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8TL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8TL.guiupdate = function() return end
- end
-MobilityTable["8Gear-T-L"] = Gear8TL
-
---8 speed gearboxes inline
-
-local Gear8LS = {}
- Gear8LS.id = "8Gear-L-S"
- Gear8LS.ent = "acf_gearbox"
- Gear8LS.type = "Mobility"
- Gear8LS.name = "8-Speed, Inline, Small"
- Gear8LS.desc = "A small and light 8 speed gearbox."
- Gear8LS.model = "models/engines/linear_s.mdl"
- Gear8LS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8LS.category = "8-Speed"
- Gear8LS.weight = Gear8SW
- Gear8LS.switch = 0.3
- Gear8LS.maxtq = GearSMT
- Gear8LS.gears = 8
- Gear8LS.doubleclutch = false
- Gear8LS.geartable = {}
- Gear8LS.geartable[-1] = 0.5
- Gear8LS.geartable[0] = 0
- Gear8LS.geartable[1] = 0.1
- Gear8LS.geartable[2] = 0.2
- Gear8LS.geartable[3] = 0.3
- Gear8LS.geartable[4] = 0.4
- Gear8LS.geartable[5] = 0.5
- Gear8LS.geartable[6] = 0.6
- Gear8LS.geartable[7] = 0.7
- Gear8LS.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8LS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8LS.guiupdate = function() return end
- end
-MobilityTable["8Gear-L-S"] = Gear8LS
-
-local Gear8LM = {}
- Gear8LM.id = "8Gear-L-M"
- Gear8LM.ent = "acf_gearbox"
- Gear8LM.type = "Mobility"
- Gear8LM.name = "8-Speed, Inline, Medium"
- Gear8LM.desc = "A medium duty 8 speed gearbox.."
- Gear8LM.model = "models/engines/linear_m.mdl"
- Gear8LM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8LM.category = "8-Speed"
- Gear8LM.weight = Gear8MW
- Gear8LM.switch = 0.4
- Gear8LM.maxtq = GearMMT
- Gear8LM.gears = 8
- Gear8LM.doubleclutch = false
- Gear8LM.geartable = {}
- Gear8LM.geartable[-1] = 0.5
- Gear8LM.geartable[0] = 0
- Gear8LM.geartable[1] = 0.1
- Gear8LM.geartable[2] = 0.2
- Gear8LM.geartable[3] = 0.3
- Gear8LM.geartable[4] = 0.4
- Gear8LM.geartable[5] = 0.5
- Gear8LM.geartable[6] = 0.6
- Gear8LM.geartable[7] = 0.7
- Gear8LM.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8LM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8LM.guiupdate = function() return end
- end
-MobilityTable["8Gear-L-M"] = Gear8LM
-
-local Gear8LL = {}
- Gear8LL.id = "8Gear-L-L"
- Gear8LL.ent = "acf_gearbox"
- Gear8LL.type = "Mobility"
- Gear8LL.name = "8-Speed, Inline, Large"
- Gear8LL.desc = "Heavy duty 8 speed gearbox, however rather heavy."
- Gear8LL.model = "models/engines/linear_l.mdl"
- Gear8LL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8LL.category = "8-Speed"
- Gear8LL.weight = Gear8LW
- Gear8LL.switch = 0.6
- Gear8LL.maxtq = GearLMT
- Gear8LL.gears = 8
- Gear8LL.doubleclutch = false
- Gear8LL.geartable = {}
- Gear8LL.geartable[-1] = 1
- Gear8LL.geartable[0] = 0
- Gear8LL.geartable[1] = 0.1
- Gear8LL.geartable[2] = 0.2
- Gear8LL.geartable[3] = 0.3
- Gear8LL.geartable[4] = 0.4
- Gear8LL.geartable[5] = 0.5
- Gear8LL.geartable[6] = 0.6
- Gear8LL.geartable[7] = 0.7
- Gear8LL.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8LL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8LL.guiupdate = function() return end
- end
-MobilityTable["8Gear-L-L"] = Gear8LL
-
-
-
-
--- 8 speed dual clutch gearboxes transaxial
-local Gear8TDS = {}
- Gear8TDS.id = "8Gear-TD-S"
- Gear8TDS.ent = "acf_gearbox"
- Gear8TDS.type = "Mobility"
- Gear8TDS.name = "8-Speed, Transaxial Dual Clutch, Small"
- Gear8TDS.desc = "A small and light 8 speed gearbox The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear8TDS.model = "models/engines/transaxial_s.mdl"
- Gear8TDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8TDS.category = "8-Speed"
- Gear8TDS.weight = Gear8SW
- Gear8TDS.switch = 0.3
- Gear8TDS.maxtq = GearSMT
- Gear8TDS.gears = 8
- Gear8TDS.doubleclutch = true
- Gear8TDS.geartable = {}
- Gear8TDS.geartable[-1] = 0.5
- Gear8TDS.geartable[0] = 0
- Gear8TDS.geartable[1] = 0.1
- Gear8TDS.geartable[2] = 0.2
- Gear8TDS.geartable[3] = 0.3
- Gear8TDS.geartable[4] = 0.4
- Gear8TDS.geartable[5] = 0.5
- Gear8TDS.geartable[6] = 0.6
- Gear8TDS.geartable[7] = 0.7
- Gear8TDS.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8TDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8TDS.guiupdate = function() return end
- end
-MobilityTable["8Gear-TD-S"] = Gear8TDS
-
-local Gear8TDM = {}
- Gear8TDM.id = "8Gear-TD-M"
- Gear8TDM.ent = "acf_gearbox"
- Gear8TDM.type = "Mobility"
- Gear8TDM.name = "8-Speed, Transaxial Dual Clutch, Medium"
- Gear8TDM.desc = "A a medium duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear8TDM.model = "models/engines/transaxial_m.mdl"
- Gear8TDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8TDM.category = "8-Speed"
- Gear8TDM.weight = Gear8MW
- Gear8TDM.switch = 0.4
- Gear8TDM.maxtq = GearMMT
- Gear8TDM.gears = 8
- Gear8TDM.doubleclutch = true
- Gear8TDM.geartable = {}
- Gear8TDM.geartable[-1] = 0.5
- Gear8TDM.geartable[0] = 0
- Gear8TDM.geartable[1] = 0.1
- Gear8TDM.geartable[2] = 0.2
- Gear8TDM.geartable[3] = 0.3
- Gear8TDM.geartable[4] = 0.4
- Gear8TDM.geartable[5] = 0.5
- Gear8TDM.geartable[6] = 0.6
- Gear8TDM.geartable[7] = 0.7
- Gear8TDM.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8TDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8TDM.guiupdate = function() return end
- end
-MobilityTable["8Gear-TD-M"] = Gear8TDM
-
-local Gear8TDL = {}
- Gear8TDL.id = "8Gear-TD-L"
- Gear8TDL.ent = "acf_gearbox"
- Gear8TDL.type = "Mobility"
- Gear8TDL.name = "8-Speed, Transaxial Dual Clutch, Large"
- Gear8TDL.desc = "Heavy duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear8TDL.model = "models/engines/transaxial_l.mdl"
- Gear8TDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8TDL.category = "8-Speed"
- Gear8TDL.weight = Gear8LW
- Gear8TDL.switch = 0.6
- Gear8TDL.maxtq = GearLMT
- Gear8TDL.gears = 8
- Gear8TDL.doubleclutch = true
- Gear8TDL.geartable = {}
- Gear8TDL.geartable[-1] = 1
- Gear8TDL.geartable[0] = 0
- Gear8TDL.geartable[1] = 0.1
- Gear8TDL.geartable[2] = 0.2
- Gear8TDL.geartable[3] = 0.3
- Gear8TDL.geartable[4] = 0.4
- Gear8TDL.geartable[5] = 0.5
- Gear8TDL.geartable[6] = 0.6
- Gear8TDL.geartable[7] = 0.7
- Gear8TDL.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8TDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8TDL.guiupdate = function() return end
- end
-MobilityTable["8Gear-TD-L"] = Gear8TDL
-
--- 8 speed dual clutch gearboxes inline
-local Gear8LDS = {}
- Gear8LDS.id = "8Gear-LD-S"
- Gear8LDS.ent = "acf_gearbox"
- Gear8LDS.type = "Mobility"
- Gear8LDS.name = "8-Speed, Inline Dual Clutch, Small"
- Gear8LDS.desc = "A small and light 8 speed gearbox The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear8LDS.model = "models/engines/linear_s.mdl"
- Gear8LDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8LDS.category = "8-Speed"
- Gear8LDS.weight = Gear8SW
- Gear8LDS.switch = 0.3
- Gear8LDS.maxtq = GearSMT
- Gear8LDS.gears = 8
- Gear8LDS.doubleclutch = true
- Gear8LDS.geartable = {}
- Gear8LDS.geartable[-1] = 0.5
- Gear8LDS.geartable[0] = 0
- Gear8LDS.geartable[1] = 0.1
- Gear8LDS.geartable[2] = 0.2
- Gear8LDS.geartable[3] = 0.3
- Gear8LDS.geartable[4] = 0.4
- Gear8LDS.geartable[5] = 0.5
- Gear8LDS.geartable[6] = 0.6
- Gear8LDS.geartable[7] = 0.7
- Gear8LDS.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8LDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8LDS.guiupdate = function() return end
- end
-MobilityTable["8Gear-LD-S"] = Gear8LDS
-
-local Gear8LDM = {}
- Gear8LDM.id = "8Gear-LD-M"
- Gear8LDM.ent = "acf_gearbox"
- Gear8LDM.type = "Mobility"
- Gear8LDM.name = "8-Speed, Inline Dual Clutch, Medium"
- Gear8LDM.desc = "A a medium duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear8LDM.model = "models/engines/linear_m.mdl"
- Gear8LDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8LDM.category = "8-Speed"
- Gear8LDM.weight = Gear8MW
- Gear8LDM.switch = 0.4
- Gear8LDM.maxtq = GearMMT
- Gear8LDM.gears = 8
- Gear8LDM.doubleclutch = true
- Gear8LDM.geartable = {}
- Gear8LDM.geartable[-1] = 0.5
- Gear8LDM.geartable[0] = 0
- Gear8LDM.geartable[1] = 0.1
- Gear8LDM.geartable[2] = 0.2
- Gear8LDM.geartable[3] = 0.3
- Gear8LDM.geartable[4] = 0.4
- Gear8LDM.geartable[5] = 0.5
- Gear8LDM.geartable[6] = 0.6
- Gear8LDM.geartable[7] = 0.7
- Gear8LDM.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8LDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8LDM.guiupdate = function() return end
- end
-MobilityTable["8Gear-LD-M"] = Gear8LDM
-
-local Gear8LDL = {}
- Gear8LDL.id = "8Gear-LD-L"
- Gear8LDL.ent = "acf_gearbox"
- Gear8LDL.type = "Mobility"
- Gear8LDL.name = "8-Speed, Inline Dual Clutch, Large"
- Gear8LDL.desc = "Heavy duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear8LDL.model = "models/engines/linear_l.mdl"
- Gear8LDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8LDL.category = "8-Speed"
- Gear8LDL.weight = Gear8LW
- Gear8LDL.switch = 0.6
- Gear8LDL.maxtq = GearLMT
- Gear8LDL.gears = 8
- Gear8LDL.doubleclutch = true
- Gear8LDL.geartable = {}
- Gear8LDL.geartable[-1] = 1
- Gear8LDL.geartable[0] = 0
- Gear8LDL.geartable[1] = 0.1
- Gear8LDL.geartable[2] = 0.2
- Gear8LDL.geartable[3] = 0.3
- Gear8LDL.geartable[4] = 0.4
- Gear8LDL.geartable[5] = 0.5
- Gear8LDL.geartable[6] = 0.6
- Gear8LDL.geartable[7] = 0.7
- Gear8LDL.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8LDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8LDL.guiupdate = function() return end
- end
-MobilityTable["8Gear-LD-L"] = Gear8LDL
-
--- 6 speed dual clutch inline gearboxes
-local Gear6LDS = {}
- Gear6LDS.id = "6Gear-LD-S"
- Gear6LDS.ent = "acf_gearbox"
- Gear6LDS.type = "Mobility"
- Gear6LDS.name = "6-Speed, Inline Dual Clutch, Small"
- Gear6LDS.desc = "A small and light 6 speed inline gearbox, with a limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6LDS.model = "models/engines/linear_s.mdl"
- Gear6LDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LDS.category = "6-Speed"
- Gear6LDS.weight = Gear6SW
- Gear6LDS.switch = 0.3
- Gear6LDS.maxtq = GearSMT
- Gear6LDS.gears = 6
- Gear6LDS.doubleclutch = true
- Gear6LDS.geartable = {}
- Gear6LDS.geartable[-1] = 0.5
- Gear6LDS.geartable[0] = 0
- Gear6LDS.geartable[1] = 0.1
- Gear6LDS.geartable[2] = 0.2
- Gear6LDS.geartable[3] = 0.3
- Gear6LDS.geartable[4] = 0.4
- Gear6LDS.geartable[5] = 0.5
- Gear6LDS.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LDS.guiupdate = function() return end
- end
-MobilityTable["6Gear-LD-S"] = Gear6LDS
-
-local Gear6LDM = {}
- Gear6LDM.id = "6Gear-LD-M"
- Gear6LDM.ent = "acf_gearbox"
- Gear6LDM.type = "Mobility"
- Gear6LDM.name = "6-Speed, Inline Dual Clutch, Medium"
- Gear6LDM.desc = "A a medium duty 6 speed inline gearbox. The added gears reduce torque capacity substantially. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6LDM.model = "models/engines/linear_m.mdl"
- Gear6LDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LDM.category = "6-Speed"
- Gear6LDM.weight = Gear6MW
- Gear6LDM.switch = 0.4
- Gear6LDM.maxtq = GearMMT
- Gear6LDM.gears = 6
- Gear6LDM.doubleclutch = true
- Gear6LDM.geartable = {}
- Gear6LDM.geartable[-1] = 0.5
- Gear6LDM.geartable[0] = 0
- Gear6LDM.geartable[1] = 0.1
- Gear6LDM.geartable[2] = 0.2
- Gear6LDM.geartable[3] = 0.3
- Gear6LDM.geartable[4] = 0.4
- Gear6LDM.geartable[5] = 0.5
- Gear6LDM.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LDM.guiupdate = function() return end
- end
-MobilityTable["6Gear-LD-M"] = Gear6LDM
-
-local Gear6LDL = {}
- Gear6LDL.id = "6Gear-LD-L"
- Gear6LDL.ent = "acf_gearbox"
- Gear6LDL.type = "Mobility"
- Gear6LDL.name = "6-Speed, Inline Dual Clutch, Large"
- Gear6LDL.desc = "Heavy duty 6 speed inline gearbox, however not as resilient as a 4 speed. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6LDL.model = "models/engines/linear_l.mdl"
- Gear6LDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LDL.category = "6-Speed"
- Gear6LDL.weight = Gear6LW
- Gear6LDL.switch = 0.6
- Gear6LDL.maxtq = GearLMT
- Gear6LDL.gears = 6
- Gear6LDL.doubleclutch = true
- Gear6LDL.geartable = {}
- Gear6LDL.geartable[-1] = 1
- Gear6LDL.geartable[0] = 0
- Gear6LDL.geartable[1] = 0.1
- Gear6LDL.geartable[2] = 0.2
- Gear6LDL.geartable[3] = 0.3
- Gear6LDL.geartable[4] = 0.4
- Gear6LDL.geartable[5] = 0.5
- Gear6LDL.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LDL.guiupdate = function() return end
- end
-MobilityTable["6Gear-LD-L"] = Gear6LDL
-
-
-
-
--- 6 speed normal inline gearboxes
-local Gear6LS = {}
- Gear6LS.id = "6Gear-L-S"
- Gear6LS.ent = "acf_gearbox"
- Gear6LS.type = "Mobility"
- Gear6LS.name = "6-Speed, Inline, Small"
- Gear6LS.desc = "A small and light 6 speed inline gearbox, with a limited max torque rating."
- Gear6LS.model = "models/engines/linear_s.mdl"
- Gear6LS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LS.category = "6-Speed"
- Gear6LS.weight = Gear6SW
- Gear6LS.switch = 0.3
- Gear6LS.maxtq = GearSMT
- Gear6LS.gears = 6
- Gear6LS.doubleclutch = false
- Gear6LS.geartable = {}
- Gear6LS.geartable[-1] = 0.5
- Gear6LS.geartable[0] = 0
- Gear6LS.geartable[1] = 0.1
- Gear6LS.geartable[2] = 0.2
- Gear6LS.geartable[3] = 0.3
- Gear6LS.geartable[4] = 0.4
- Gear6LS.geartable[5] = 0.5
- Gear6LS.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LS.guiupdate = function() return end
- end
-MobilityTable["6Gear-L-S"] = Gear6LS
-
-local Gear6LM = {}
- Gear6LM.id = "6Gear-L-M"
- Gear6LM.ent = "acf_gearbox"
- Gear6LM.type = "Mobility"
- Gear6LM.name = "6-Speed, Inline, Medium"
- Gear6LM.desc = "A medium duty 6 speed inline gearbox with a limited torque rating."
- Gear6LM.model = "models/engines/linear_m.mdl"
- Gear6LM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LM.category = "6-Speed"
- Gear6LM.weight = Gear6MW
- Gear6LM.switch = 0.4
- Gear6LM.maxtq = GearMMT
- Gear6LM.gears = 6
- Gear6LM.doubleclutch = false
- Gear6LM.geartable = {}
- Gear6LM.geartable[-1] = 0.5
- Gear6LM.geartable[0] = 0
- Gear6LM.geartable[1] = 0.1
- Gear6LM.geartable[2] = 0.2
- Gear6LM.geartable[3] = 0.3
- Gear6LM.geartable[4] = 0.4
- Gear6LM.geartable[5] = 0.5
- Gear6LM.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LM.guiupdate = function() return end
- end
-MobilityTable["6Gear-L-M"] = Gear6LM
-
-local Gear6LL = {}
- Gear6LL.id = "6Gear-L-L"
- Gear6LL.ent = "acf_gearbox"
- Gear6LL.type = "Mobility"
- Gear6LL.name = "6-Speed, Inline, Large"
- Gear6LL.desc = "Heavy duty 6 speed inline gearbox, however not as resilient as a 4 speed."
- Gear6LL.model = "models/engines/linear_l.mdl"
- Gear6LL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LL.category = "6-Speed"
- Gear6LL.weight = Gear6LW
- Gear6LL.switch = 0.6
- Gear6LL.maxtq = GearLMT
- Gear6LL.gears = 6
- Gear6LL.doubleclutch = false
- Gear6LL.geartable = {}
- Gear6LL.geartable[-1] = 1
- Gear6LL.geartable[0] = 0
- Gear6LL.geartable[1] = 0.1
- Gear6LL.geartable[2] = 0.2
- Gear6LL.geartable[3] = 0.3
- Gear6LL.geartable[4] = 0.4
- Gear6LL.geartable[5] = 0.5
- Gear6LL.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LL.guiupdate = function() return end
- end
-MobilityTable["6Gear-L-L"] = Gear6LL
-
-
-
-
-
-
--- 4 speed normal inline gearboxes
-local Gear4LS = {}
- Gear4LS.id = "4Gear-L-S"
- Gear4LS.ent = "acf_gearbox"
- Gear4LS.type = "Mobility"
- Gear4LS.name = "4-Speed, Inline, Small"
- Gear4LS.desc = "A small, and light 4 speed inline gearbox, with a somewhat limited max torque rating\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear4LS.model = "models/engines/linear_s.mdl"
- Gear4LS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4LS.category = "4-Speed"
- Gear4LS.weight = Gear4SW
- Gear4LS.switch = 0.3
- Gear4LS.maxtq = GearSMT
- Gear4LS.gears = 4
- Gear4LS.doubleclutch = false
- Gear4LS.geartable = {}
- Gear4LS.geartable[-1] = 0.5
- Gear4LS.geartable[0] = 0
- Gear4LS.geartable[1] = 0.1
- Gear4LS.geartable[2] = 0.2
- Gear4LS.geartable[3] = 0.3
- Gear4LS.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4LS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4LS.guiupdate = function() return end
- end
-MobilityTable["4Gear-L-S"] = Gear4LS
-
-local Gear4LM = {}
- Gear4LM.id = "4Gear-L-M"
- Gear4LM.ent = "acf_gearbox"
- Gear4LM.type = "Mobility"
- Gear4LM.name = "4-Speed, Inline, Medium"
- Gear4LM.desc = "A medium sized, 4 speed inline gearbox"
- Gear4LM.model = "models/engines/linear_m.mdl"
- Gear4LM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4LM.category = "4-Speed"
- Gear4LM.weight = Gear4MW
- Gear4LM.switch = 0.4
- Gear4LM.maxtq = GearMMT
- Gear4LM.gears = 4
- Gear4LM.doubleclutch = false
- Gear4LM.geartable = {}
- Gear4LM.geartable[-1] = 0.5
- Gear4LM.geartable[0] = 0
- Gear4LM.geartable[1] = 0.1
- Gear4LM.geartable[2] = 0.2
- Gear4LM.geartable[3] = 0.3
- Gear4LM.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4LM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4LM.guiupdate = function() return end
- end
-MobilityTable["4Gear-L-M"] = Gear4LM
-
-local Gear4LL = {}
- Gear4LL.id = "4Gear-L-L"
- Gear4LL.ent = "acf_gearbox"
- Gear4LL.type = "Mobility"
- Gear4LL.name = "4-Speed, Inline, Large"
- Gear4LL.desc = "A large, heavy and sturdy 4 speed inline gearbox"
- Gear4LL.model = "models/engines/linear_l.mdl"
- Gear4LL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4LL.category = "4-Speed"
- Gear4LL.weight = Gear4LW
- Gear4LL.switch = 0.6
- Gear4LL.maxtq = GearLMT
- Gear4LL.gears = 4
- Gear4LL.doubleclutch = false
- Gear4LL.geartable = {}
- Gear4LL.geartable[-1] = 1
- Gear4LL.geartable[0] = 0
- Gear4LL.geartable[1] = 0.1
- Gear4LL.geartable[2] = 0.2
- Gear4LL.geartable[3] = 0.3
- Gear4LL.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4LL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4LL.guiupdate = function() return end
- end
-MobilityTable["4Gear-L-L"] = Gear4LL
-
-
-
-
--- 4 speed inline dual clutch gearboxes
-local Gear4TLS = {}
- Gear4TLS.id = "4Gear-LD-S"
- Gear4TLS.ent = "acf_gearbox"
- Gear4TLS.type = "Mobility"
- Gear4TLS.name = "4-Speed, Inline Dual Clutch, Small"
- Gear4TLS.desc = "A small, and light 4 speed inline gearbox, with a somewhat limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear4TLS.model = "models/engines/linear_s.mdl"
- Gear4TLS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TLS.category = "4-Speed"
- Gear4TLS.weight = Gear4SW
- Gear4TLS.switch = 0.3
- Gear4TLS.maxtq = GearSMT
- Gear4TLS.gears = 4
- Gear4TLS.doubleclutch = true
- Gear4TLS.geartable = {}
- Gear4TLS.geartable[-1] = 0.5
- Gear4TLS.geartable[0] = 0
- Gear4TLS.geartable[1] = 0.1
- Gear4TLS.geartable[2] = 0.2
- Gear4TLS.geartable[3] = 0.3
- Gear4TLS.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TLS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TLS.guiupdate = function() return end
- end
-MobilityTable["4Gear-LD-S"] = Gear4TLS
-
-local Gear4TLM = {}
- Gear4TLM.id = "4Gear-LD-M"
- Gear4TLM.ent = "acf_gearbox"
- Gear4TLM.type = "Mobility"
- Gear4TLM.name = "4-Speed, Inline Dual Clutch, Medium"
- Gear4TLM.desc = "A medium sized, 4 speed inline gearbox. The dual clutch allows you to apply power and brake each side independently"
- Gear4TLM.model = "models/engines/linear_m.mdl"
- Gear4TLM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4TLM.category = "4-Speed"
- Gear4TLM.weight = Gear4MW
- Gear4TLM.switch = 0.4
- Gear4TLM.maxtq = GearMMT
- Gear4TLM.gears = 4
- Gear4TLM.doubleclutch = true
- Gear4TLM.geartable = {}
- Gear4TLM.geartable[-1] = 0.5
- Gear4TLM.geartable[0] = 0
- Gear4TLM.geartable[1] = 0.1
- Gear4TLM.geartable[2] = 0.2
- Gear4TLM.geartable[3] = 0.3
- Gear4TLM.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4TLM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4TLM.guiupdate = function() return end
- end
-MobilityTable["4Gear-LD-M"] = Gear4TLM
-
-local Gear4LDL = {}
- Gear4LDL.id = "4Gear-LD-L"
- Gear4LDL.ent = "acf_gearbox"
- Gear4LDL.type = "Mobility"
- Gear4LDL.name = "4-Speed, Inline Dual Clutch, Large"
- Gear4LDL.desc = "A large, heavy and sturdy 4 speed inline gearbox. The dual clutch allows you to apply power and brake each side independently"
- Gear4LDL.model = "models/engines/linear_l.mdl"
- Gear4LDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4LDL.category = "4-Speed"
- Gear4LDL.weight = Gear4LW
- Gear4LDL.switch = 0.6
- Gear4LDL.maxtq = GearLMT
- Gear4LDL.gears = 4
- Gear4LDL.doubleclutch = true
- Gear4LDL.geartable = {}
- Gear4LDL.geartable[-1] = 1
- Gear4LDL.geartable[0] = 0
- Gear4LDL.geartable[1] = 0.1
- Gear4LDL.geartable[2] = 0.2
- Gear4LDL.geartable[3] = 0.3
- Gear4LDL.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4LDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4LDL.guiupdate = function() return end
- end
-MobilityTable["4Gear-LD-L"] = Gear4LDL
-
-
-
-
--- 6 speed normal inline gearboxes
-local Gear6LS = {}
- Gear6LS.id = "6Gear-L-S"
- Gear6LS.ent = "acf_gearbox"
- Gear6LS.type = "Mobility"
- Gear6LS.name = "6-Speed, Inline, Small"
- Gear6LS.desc = "A small and light 6 speed inline gearbox, with a limited max torque rating."
- Gear6LS.model = "models/engines/linear_s.mdl"
- Gear6LS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LS.category = "6-Speed"
- Gear6LS.weight = Gear6SW
- Gear6LS.switch = 0.3
- Gear6LS.maxtq = GearSMT
- Gear6LS.gears = 6
- Gear6LS.doubleclutch = false
- Gear6LS.geartable = {}
- Gear6LS.geartable[-1] = 0.5
- Gear6LS.geartable[0] = 0
- Gear6LS.geartable[1] = 0.1
- Gear6LS.geartable[2] = 0.2
- Gear6LS.geartable[3] = 0.3
- Gear6LS.geartable[4] = 0.4
- Gear6LS.geartable[5] = 0.5
- Gear6LS.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LS.guiupdate = function() return end
- end
-MobilityTable["6Gear-L-S"] = Gear6LS
-
-local Gear6LM = {}
- Gear6LM.id = "6Gear-L-M"
- Gear6LM.ent = "acf_gearbox"
- Gear6LM.type = "Mobility"
- Gear6LM.name = "6-Speed, Inline, Medium"
- Gear6LM.desc = "A medium duty 6 speed inline gearbox with a limited torque rating."
- Gear6LM.model = "models/engines/linear_m.mdl"
- Gear6LM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LM.category = "6-Speed"
- Gear6LM.weight = Gear6MW
- Gear6LM.switch = 0.4
- Gear6LM.maxtq = GearMMT
- Gear6LM.gears = 6
- Gear6LM.doubleclutch = false
- Gear6LM.geartable = {}
- Gear6LM.geartable[-1] = 0.5
- Gear6LM.geartable[0] = 0
- Gear6LM.geartable[1] = 0.1
- Gear6LM.geartable[2] = 0.2
- Gear6LM.geartable[3] = 0.3
- Gear6LM.geartable[4] = 0.4
- Gear6LM.geartable[5] = 0.5
- Gear6LM.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LM.guiupdate = function() return end
- end
-MobilityTable["6Gear-L-M"] = Gear6LM
-
-local Gear6LL = {}
- Gear6LL.id = "6Gear-L-L"
- Gear6LL.ent = "acf_gearbox"
- Gear6LL.type = "Mobility"
- Gear6LL.name = "6-Speed, Inline, Large"
- Gear6LL.desc = "Heavy duty 6 speed inline gearbox, however not as resilient as a 4 speed."
- Gear6LL.model = "models/engines/linear_l.mdl"
- Gear6LL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LL.category = "6-Speed"
- Gear6LL.weight = Gear6LW
- Gear6LL.switch = 0.6
- Gear6LL.maxtq = GearLMT
- Gear6LL.gears = 6
- Gear6LL.doubleclutch = false
- Gear6LL.geartable = {}
- Gear6LL.geartable[-1] = 1
- Gear6LL.geartable[0] = 0
- Gear6LL.geartable[1] = 0.1
- Gear6LL.geartable[2] = 0.2
- Gear6LL.geartable[3] = 0.3
- Gear6LL.geartable[4] = 0.4
- Gear6LL.geartable[5] = 0.5
- Gear6LL.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LL.guiupdate = function() return end
- end
-MobilityTable["6Gear-L-L"] = Gear6LL
-
-
-
-
-
--- 6 speed dual clutch inline gearboxes
-local Gear6LDS = {}
- Gear6LDS.id = "6Gear-LD-S"
- Gear6LDS.ent = "acf_gearbox"
- Gear6LDS.type = "Mobility"
- Gear6LDS.name = "6-Speed, Inline Dual Clutch, Small"
- Gear6LDS.desc = "A small and light 6 speed inline gearbox, with a limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6LDS.model = "models/engines/linear_s.mdl"
- Gear6LDS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LDS.category = "6-Speed"
- Gear6LDS.weight = Gear6SW
- Gear6LDS.switch = 0.3
- Gear6LDS.maxtq = GearSMT
- Gear6LDS.gears = 6
- Gear6LDS.doubleclutch = true
- Gear6LDS.geartable = {}
- Gear6LDS.geartable[-1] = 0.5
- Gear6LDS.geartable[0] = 0
- Gear6LDS.geartable[1] = 0.1
- Gear6LDS.geartable[2] = 0.2
- Gear6LDS.geartable[3] = 0.3
- Gear6LDS.geartable[4] = 0.4
- Gear6LDS.geartable[5] = 0.5
- Gear6LDS.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LDS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LDS.guiupdate = function() return end
- end
-MobilityTable["6Gear-LD-S"] = Gear6LDS
-
-local Gear6LDM = {}
- Gear6LDM.id = "6Gear-LD-M"
- Gear6LDM.ent = "acf_gearbox"
- Gear6LDM.type = "Mobility"
- Gear6LDM.name = "6-Speed, Inline Dual Clutch, Medium"
- Gear6LDM.desc = "A a medium duty 6 speed inline gearbox. The added gears reduce torque capacity substantially. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6LDM.model = "models/engines/linear_m.mdl"
- Gear6LDM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LDM.category = "6-Speed"
- Gear6LDM.weight = Gear6MW
- Gear6LDM.switch = 0.4
- Gear6LDM.maxtq = GearMMT
- Gear6LDM.gears = 6
- Gear6LDM.doubleclutch = true
- Gear6LDM.geartable = {}
- Gear6LDM.geartable[-1] = 0.5
- Gear6LDM.geartable[0] = 0
- Gear6LDM.geartable[1] = 0.1
- Gear6LDM.geartable[2] = 0.2
- Gear6LDM.geartable[3] = 0.3
- Gear6LDM.geartable[4] = 0.4
- Gear6LDM.geartable[5] = 0.5
- Gear6LDM.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LDM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LDM.guiupdate = function() return end
- end
-MobilityTable["6Gear-LD-M"] = Gear6LDM
-
-local Gear6LDL = {}
- Gear6LDL.id = "6Gear-LD-L"
- Gear6LDL.ent = "acf_gearbox"
- Gear6LDL.type = "Mobility"
- Gear6LDL.name = "6-Speed, Inline Dual Clutch, Large"
- Gear6LDL.desc = "Heavy duty 6 speed inline gearbox, however not as resilient as a 4 speed. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios"
- Gear6LDL.model = "models/engines/linear_l.mdl"
- Gear6LDL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6LDL.category = "6-Speed"
- Gear6LDL.weight = Gear6LW
- Gear6LDL.switch = 0.6
- Gear6LDL.maxtq = GearLMT
- Gear6LDL.gears = 6
- Gear6LDL.doubleclutch = true
- Gear6LDL.geartable = {}
- Gear6LDL.geartable[-1] = 1
- Gear6LDL.geartable[0] = 0
- Gear6LDL.geartable[1] = 0.1
- Gear6LDL.geartable[2] = 0.2
- Gear6LDL.geartable[3] = 0.3
- Gear6LDL.geartable[4] = 0.4
- Gear6LDL.geartable[5] = 0.5
- Gear6LDL.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6LDL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6LDL.guiupdate = function() return end
- end
-MobilityTable["6Gear-LD-L"] = Gear6LDL
-
---Straight through gearboxes
-local Gear4STS = {}
- Gear4STS.id = "4Gear-ST-S"
- Gear4STS.ent = "acf_gearbox"
- Gear4STS.type = "Mobility"
- Gear4STS.name = "4-Speed, Straight, Small"
- Gear4STS.desc = "A small straight-through gearbox"
- Gear4STS.model = "models/engines/t5small.mdl"
- Gear4STS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4STS.category = "4-Speed"
- Gear4STS.weight = Gear4SW
- Gear4STS.switch = 0.3
- Gear4STS.maxtq = GearSMT
- Gear4STS.gears = 4
- Gear4STS.doubleclutch = false
- Gear4STS.geartable = {}
- Gear4STS.geartable[-1] = 1
- Gear4STS.geartable[0] = 0
- Gear4STS.geartable[1] = 0.1
- Gear4STS.geartable[2] = 0.2
- Gear4STS.geartable[3] = 0.3
- Gear4STS.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4STS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4STS.guiupdate = function() return end
- end
-MobilityTable["4Gear-ST-S"] = Gear4STS
-
-local Gear4STM = {}
- Gear4STM.id = "4Gear-ST-M"
- Gear4STM.ent = "acf_gearbox"
- Gear4STM.type = "Mobility"
- Gear4STM.name = "4-Speed, Straight, Medium"
- Gear4STM.desc = "A medium sized, 4 speed straight-through gearbox."
- Gear4STM.model = "models/engines/t5med.mdl"
- Gear4STM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4STM.category = "4-Speed"
- Gear4STM.weight = Gear4MW
- Gear4STM.switch = 0.4
- Gear4STM.maxtq = GearMMT
- Gear4STM.gears = 4
- Gear4STM.doubleclutch = false
- Gear4STM.geartable = {}
- Gear4STM.geartable[-1] = 0.5
- Gear4STM.geartable[0] = 0
- Gear4STM.geartable[1] = 0.1
- Gear4STM.geartable[2] = 0.2
- Gear4STM.geartable[3] = 0.3
- Gear4STM.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4STM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4STM.guiupdate = function() return end
- end
-MobilityTable["4Gear-ST-M"] = Gear4STM
-
-local Gear4STL = {}
- Gear4STL.id = "4Gear-ST-L"
- Gear4STL.ent = "acf_gearbox"
- Gear4STL.type = "Mobility"
- Gear4STL.name = "4-Speed, Straight, Large"
- Gear4STL.desc = "A large sized, 4 speed straight-through gearbox."
- Gear4STL.model = "models/engines/t5large.mdl"
- Gear4STL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear4STL.category = "4-Speed"
- Gear4STL.weight = Gear4LW
- Gear4STL.switch = 0.6
- Gear4STL.maxtq = GearLMT
- Gear4STL.gears = 4
- Gear4STL.doubleclutch = false
- Gear4STL.geartable = {}
- Gear4STL.geartable[-1] = 0.5
- Gear4STL.geartable[0] = 0
- Gear4STL.geartable[1] = 0.1
- Gear4STL.geartable[2] = 0.2
- Gear4STL.geartable[3] = 0.3
- Gear4STL.geartable[4] = -0.1
- if ( CLIENT ) then
- Gear4STL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear4STL.guiupdate = function() return end
- end
-MobilityTable["4Gear-ST-L"] = Gear4STL
-
-local Gear6STS = {}
- Gear6STS.id = "6Gear-ST-S"
- Gear6STS.ent = "acf_gearbox"
- Gear6STS.type = "Mobility"
- Gear6STS.name = "6-Speed, Straight, Small"
- Gear6STS.desc = "A small and light 6 speed straight-through gearbox."
- Gear6STS.model = "models/engines/t5small.mdl"
- Gear6STS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6STS.category = "6-Speed"
- Gear6STS.weight = Gear6SW
- Gear6STS.switch = 0.3
- Gear6STS.maxtq = GearSMT
- Gear6STS.gears = 6
- Gear6STS.doubleclutch = false
- Gear6STS.geartable = {}
- Gear6STS.geartable[-1] = 0.5
- Gear6STS.geartable[0] = 0
- Gear6STS.geartable[1] = 0.1
- Gear6STS.geartable[2] = 0.2
- Gear6STS.geartable[3] = 0.3
- Gear6STS.geartable[4] = 0.4
- Gear6STS.geartable[5] = 0.5
- Gear6STS.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6STS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6STS.guiupdate = function() return end
- end
-MobilityTable["6Gear-ST-S"] = Gear6STS
-
-local Gear6STM = {}
- Gear6STM.id = "6Gear-ST-M"
- Gear6STM.ent = "acf_gearbox"
- Gear6STM.type = "Mobility"
- Gear6STM.name = "6-Speed, Straight, Medium"
- Gear6STM.desc = "A medium 6 speed straight-through gearbox."
- Gear6STM.model = "models/engines/t5med.mdl"
- Gear6STM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6STM.category = "6-Speed"
- Gear6STM.weight = Gear6MW
- Gear6STM.switch = 0.4
- Gear6STM.maxtq = GearMMT
- Gear6STM.gears = 6
- Gear6STM.doubleclutch = false
- Gear6STM.geartable = {}
- Gear6STM.geartable[-1] = 0.5
- Gear6STM.geartable[0] = 0
- Gear6STM.geartable[1] = 0.1
- Gear6STM.geartable[2] = 0.2
- Gear6STM.geartable[3] = 0.3
- Gear6STM.geartable[4] = 0.4
- Gear6STM.geartable[5] = 0.5
- Gear6STM.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6STM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6STM.guiupdate = function() return end
- end
-MobilityTable["6Gear-ST-M"] = Gear6STM
-
-
-
-
-local Gear6STL = {}
- Gear6STL.id = "6Gear-ST-L"
- Gear6STL.ent = "acf_gearbox"
- Gear6STL.type = "Mobility"
- Gear6STL.name = "6-Speed, Straight, Large"
- Gear6STL.desc = "A large 6 speed straight-through gearbox."
- Gear6STL.model = "models/engines/t5large.mdl"
- Gear6STL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear6STL.category = "6-Speed"
- Gear6STL.weight = Gear6LW
- Gear6STL.switch = 0.6
- Gear6STL.maxtq = GearLMT
- Gear6STL.gears = 6
- Gear6STL.doubleclutch = false
- Gear6STL.geartable = {}
- Gear6STL.geartable[-1] = 0.5
- Gear6STL.geartable[0] = 0
- Gear6STL.geartable[1] = 0.1
- Gear6STL.geartable[2] = 0.2
- Gear6STL.geartable[3] = 0.3
- Gear6STL.geartable[4] = 0.4
- Gear6STL.geartable[5] = 0.5
- Gear6STL.geartable[6] = -0.1
- if ( CLIENT ) then
- Gear6STL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear6STL.guiupdate = function() return end
- end
-MobilityTable["6Gear-ST-L"] = Gear6STL
-
-local Gear8STS = {}
- Gear8STS.id = "8Gear-ST-S"
- Gear8STS.ent = "acf_gearbox"
- Gear8STS.type = "Mobility"
- Gear8STS.name = "8-Speed, Straight, Small"
- Gear8STS.desc = "A small and light 8 speed straight-through gearbox."
- Gear8STS.model = "models/engines/t5small.mdl"
- Gear8STS.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8STS.category = "8-Speed"
- Gear8STS.weight = Gear8SW
- Gear8STS.switch = 0.3
- Gear8STS.maxtq = GearSMT
- Gear8STS.gears = 8
- Gear8STS.doubleclutch = false
- Gear8STS.geartable = {}
- Gear8STS.geartable[-1] = 0.5
- Gear8STS.geartable[0] = 0
- Gear8STS.geartable[1] = 0.1
- Gear8STS.geartable[2] = 0.2
- Gear8STS.geartable[3] = 0.3
- Gear8STS.geartable[4] = 0.4
- Gear8STS.geartable[5] = 0.5
- Gear8STS.geartable[6] = 0.6
- Gear8STS.geartable[7] = 0.7
- Gear8STS.geartable[8] = 0.8
- if ( CLIENT ) then
- Gear8STS.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8STS.guiupdate = function() return end
- end
-MobilityTable["8Gear-ST-S"] = Gear8STS
-
-local Gear8STM = {}
- Gear8STM.id = "8Gear-ST-M"
- Gear8STM.ent = "acf_gearbox"
- Gear8STM.type = "Mobility"
- Gear8STM.name = "8-Speed, Straight, Medium"
- Gear8STM.desc = "A medium 8 speed straight-through gearbox."
- Gear8STM.model = "models/engines/t5med.mdl"
- Gear8STM.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8STM.category = "8-Speed"
- Gear8STM.weight = Gear8MW
- Gear8STM.switch = 0.4
- Gear8STM.maxtq = GearMMT
- Gear8STM.gears = 8
- Gear8STM.doubleclutch = false
- Gear8STM.geartable = {}
- Gear8STM.geartable[-1] = 0.5
- Gear8STM.geartable[0] = 0
- Gear8STM.geartable[1] = 0.1
- Gear8STM.geartable[2] = 0.2
- Gear8STM.geartable[3] = 0.3
- Gear8STM.geartable[4] = 0.4
- Gear8STM.geartable[5] = 0.5
- Gear8STM.geartable[6] = 0.6
- Gear8STM.geartable[7] = 0.7
- Gear8STM.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8STM.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8STM.guiupdate = function() return end
- end
-MobilityTable["8Gear-ST-M"] = Gear8STM
-
-
-
-
-local Gear8STL = {}
- Gear8STL.id = "8Gear-ST-L"
- Gear8STL.ent = "acf_gearbox"
- Gear8STL.type = "Mobility"
- Gear8STL.name = "8-Speed, Straight, Large"
- Gear8STL.desc = "A large 8 speed straight-through gearbox."
- Gear8STL.model = "models/engines/t5large.mdl"
- Gear8STL.sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
- Gear8STL.category = "8-Speed"
- Gear8STL.weight = Gear8LW
- Gear8STL.switch = 0.6
- Gear8STL.maxtq = GearLMT
- Gear8STL.gears = 8
- Gear8STL.doubleclutch = false
- Gear8STL.geartable = {}
- Gear8STL.geartable[-1] = 0.5
- Gear8STL.geartable[0] = 0
- Gear8STL.geartable[1] = 0.1
- Gear8STL.geartable[2] = 0.2
- Gear8STL.geartable[3] = 0.3
- Gear8STL.geartable[4] = 0.4
- Gear8STL.geartable[5] = 0.5
- Gear8STL.geartable[6] = 0.6
- Gear8STL.geartable[7] = 0.7
- Gear8STL.geartable[8] = -0.1
- if ( CLIENT ) then
- Gear8STL.guicreate = (function( Panel, Table ) ACFGearboxGUICreate( Table ) end or nil)
- Gear8STL.guiupdate = function() return end
- end
-MobilityTable["8Gear-ST-L"] = Gear8STL
-
-
-
--- local Tracks = {}
- -- Tracks.id = "CarV8"
- -- Tracks.ent = "acf_engine"
- -- Tracks.type = "Mobility"
- -- Tracks.name = "Track"
- -- Tracks.desc = "Tank tracks"
- -- Tracks.model = "models/vehicle/vehicle_engine_block.mdl"
- -- Tracks.weight = 200
- -- if ( CLIENT ) then
- -- Tracks.guicreate = (function( Panel, Table ) ACFTrackGUICreate( Table ) end or nil)
- -- Tracks.guiupdate = function() return end
- -- end
--- MobilityTable["Tracks"] = Tracks
-
-list.Set( "ACFEnts", "Mobility", MobilityTable ) --end mobility listing
\ No newline at end of file
diff --git a/lua/ACF/Shared/ACFSensorList.lua b/lua/ACF/Shared/ACFSensorList.lua
deleted file mode 100644
index b30d98411..000000000
--- a/lua/ACF/Shared/ACFSensorList.lua
+++ /dev/null
@@ -1,19 +0,0 @@
-AddCSLuaFile( "acf/shared/acfsensorlist.lua" )
-
-local SensorTable = {} --Start sensors listing
-
-local Stabiliser = {}
- Stabiliser.id = "Stabiliser"
- Stabiliser.ent = "acf_viewpod"
- Stabiliser.type = "Sensors"
- Stabiliser.name = "Stabiliser"
- Stabiliser.desc = "Pod view stabiliser"
- Stabiliser.model = "models/jaanus/wiretool/wiretool_siren.mdl"
- Stabiliser.weight = 20
- if ( CLIENT ) then
- Stabiliser.guicreate = (function( Panel, Table ) ACFViewPodGUICreate( Table ) end or nil)
- Stabiliser.guiupdate = function() return end
- end
-SensorTable["Stabiliser"] = Stabiliser
-
-list.Set( "ACFEnts", "Sensors", SensorTable ) --end sensors listing
\ No newline at end of file
diff --git a/lua/ACF/Shared/Rounds/RoundAP.lua b/lua/ACF/Shared/Rounds/RoundAP.lua
deleted file mode 100644
index b712b6c8c..000000000
--- a/lua/ACF/Shared/Rounds/RoundAP.lua
+++ /dev/null
@@ -1,231 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundap.lua" )
-
-local DefTable = {}
- DefTable.type = "Ammo" --Tells the spawn menu what entity to spawn
- DefTable.name = "Armour Piercing (AP)" --Human readable name
- DefTable.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
- DefTable.desc = "A shell made out of a solid piece of steel, meant to penetrate armour"
- DefTable.netid = 1 --Unique ammotype ID for network transmission
-
- DefTable.create = function( Gun, BulletData ) ACF_APCreate( Gun, BulletData ) end
- DefTable.convert = function( Crate, Table ) local Result = ACF_APConvert( Crate, Table ) return Result end
- DefTable.network = function( Crate, BulletData ) ACF_APNetworkData( Crate, BulletData ) end
- DefTable.cratetxt = function( Crate ) local Result = ACF_APCrateDisplay( Crate ) return Result end
-
- DefTable.propimpact = function( Bullet, Index, Target, HitNormal, HitPos , Bone ) local Result = ACF_APPropImpact( Bullet, Index, Target, HitNormal, HitPos , Bone ) return Result end
- DefTable.worldimpact = function( Bullet, Index, HitPos, HitNormal ) local Result = ACF_APWorldImpact( Bullet, Index, HitPos, HitNormal ) return Result end
- DefTable.endflight = function( Bullet, Index, HitPos, HitNormal ) ACF_APEndFlight( Bullet, Index, HitPos, HitNormal ) end
-
- DefTable.endeffect = function( Effect, Bullet ) ACF_APEndEffect( Effect, Bullet ) end
- DefTable.pierceeffect = function( Effect, Bullet ) ACF_APPierceEffect( Effect, Bullet ) end
- DefTable.ricocheteffect = function( Effect, Bullet ) ACF_APRicochetEffect( Effect, Bullet ) end
-
- DefTable.guicreate = function( Panel, Table ) ACF_APGUICreate( Panel, Table ) end --References the function to use to draw that round menu
- DefTable.guiupdate = function( Panel, Table ) ACF_APGUIUpdate( Panel, Table ) end --References the function to use to update that round menu
-
-list.Set( "ACFRoundTypes", "AP", DefTable ) --Set the round properties
-list.Set( "ACFIdRounds", DefTable.netid , "AP" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
-
-ACF.AmmoBlacklist["AP"] = { "MO" }
-
-function ACF_APConvert( Crate, PlayerData ) --Function to convert the player's slider data into the complete round data
-
- local Data = {}
- local ServerData = {}
- local GUIData = {}
-
- if not PlayerData["PropLength"] then PlayerData["PropLength"] = 0 end
- if not PlayerData["ProjLength"] then PlayerData["ProjLength"] = 0 end
- if not PlayerData["Data10"] then PlayerData["Data10"] = 0 end
-
- PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
-
- Data["ProjMass"] = Data["FrAera"] * (Data["ProjLength"]*7.9/1000) --Volume of the projectile as a cylinder * density of steel
- Data["ShovePower"] = 0.2
- Data["PenAera"] = Data["FrAera"]^ACF.PenAreaMod
- Data["DragCoef"] = ((Data["FrAera"]/10000)/Data["ProjMass"])
- Data["LimitVel"] = 800 --Most efficient penetration speed in m/s
- Data["KETransfert"] = 0.1 --Kinetic energy transfert to the target for movement purposes
- Data["Ricochet"] = 75 --Base ricochet angle
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
-
- Data["BoomPower"] = Data["PropMass"]
-
- if SERVER then --Only the crates need this part
- ServerData["Id"] = PlayerData["Id"]
- ServerData["Type"] = PlayerData["Type"]
- return table.Merge(Data,ServerData)
- end
-
- if CLIENT then --Only tthe GUI needs this part
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"], Data["LimitVel"] )
- GUIData["MaxPen"] = (Energy.Penetration/Data["PenAera"])*ACF.KEtoRHA
- return table.Merge(Data,GUIData)
- end
-
-end
-
-function ACF_APCreate( Gun, BulletData )
-
- ACF_CreateBullet( BulletData )
-
-end
-
-function ACF_APPropImpact( Index, Bullet, Target, HitNormal, HitPos , Bone ) --Can be called from other round types
-
- if ACF_Check( Target ) then
-
- local Speed = Bullet["Flight"]:Length() / ACF.VelScale
- local Energy = ACF_Kinetic( Speed , Bullet["ProjMass"], Bullet["LimitVel"] )
- local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
-
- if HitRes.Overkill > 0 then
- table.insert( Bullet["Filter"] , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
- ACF_Spall( HitPos , Bullet["Flight"] , Bullet["Filter"] , Energy.Kinetic*HitRes.Loss , Bullet["Caliber"] , Target.ACF.Armour , Bullet["Owner"] ) --Do some spalling
- Bullet["Flight"] = Bullet["Flight"]:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet["ProjMass"])^0.5 * 39.37
- return "Penetrated"
- elseif HitRes.Ricochet then
- return "Ricochet"
- else
- return false
- end
- else
- table.insert( Bullet["Filter"] , Target )
- return "Penetrated" end
-
-end
-
-function ACF_APWorldImpact( Index, Bullet, HitPos, HitNormal )
-
- local Energy = ACF_Kinetic( Bullet["Flight"]:Length() / ACF.VelScale, Bullet["ProjMass"], Bullet["LimitVel"] )
- local Retry = ACF_PenetrateGround( Bullet, Energy, HitPos )
- if Retry then
- return "Penetrated"
- else
- return false
- end
-
-end
-
-function ACF_APEndFlight( Index, Bullet, HitPos )
-
- ACF_RemoveBullet( Index )
-
-end
-
---Ammocrate stuff
-function ACF_APNetworkData( Crate, BulletData )
-
- Crate:SetNetworkedString("AmmoType","AP")
- Crate:SetNetworkedString("AmmoID",BulletData["Id"])
- Crate:SetNetworkedInt("Caliber",BulletData["Caliber"])
- Crate:SetNetworkedInt("ProjMass",BulletData["ProjMass"])
- Crate:SetNetworkedInt("PropMass",BulletData["PropMass"])
- Crate:SetNetworkedInt("DragCoef",BulletData["DragCoef"])
- Crate:SetNetworkedInt("MuzzleVel",BulletData["MuzzleVel"])
- Crate:SetNetworkedInt("Tracer",BulletData["Tracer"])
-
-end
-
-function ACF_APCrateDisplay( Crate )
-
- local Tracer = ""
- if Crate:GetNetworkedInt("Tracer") > 0 then Tracer = "-T" end
-
- local ProjMass = math.floor(Crate:GetNetworkedString("ProjMass")*1000)
- local PropMass = math.floor(Crate:GetNetworkedString("PropMass")*1000)
-
- local txt = "Round Mass : "..ProjMass.." g\nPropellant : "..PropMass.." g"
-
- return txt
-end
-
---Clientside effects, called from ACF_Bulleteffect
-function ACF_APEndEffect( Effect, Bullet ) --Bullet stops here, do what you have to do clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Impact", Spall )
-
-end
-
-function ACF_APPierceEffect( Effect, Bullet ) --Bullet penetrated something, do what you have to clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Penetration", Spall )
-
-end
-
-function ACF_APRicochetEffect( Effect, Bullet ) --Bullet ricocheted off something, do what you have to clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Ricochet", Spall )
-
-end
-
---GUI stuff after this
-function ACF_APGUICreate( Panel, Table )
-
- acfmenupanel:AmmoSelect( ACF.AmmoBlacklist["AP"] )
-
- acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
-
- acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
-
- ACF_APGUIUpdate( Panel, Table )
-
-end
-
-function ACF_APGUIUpdate( Panel, Table )
-
- local PlayerData = {}
- PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI
- PlayerData["Type"] = "AP" --Hardcoded, match ACFRoundTypes table index
- PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider
- PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider
- --PlayerData["Data5"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data6"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data7"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data8"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data9"] = acfmenupanel.AmmoData[Name] --Not used
- local Tracer = 0
- if acfmenupanel.AmmoData["Tracer"] then Tracer = 1 end
- PlayerData["Data10"] = Tracer --Tracer
-
- local Data = ACF_APConvert( Panel, PlayerData )
-
- RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData["Data"]["id"] )
- RunConsoleCommand( "acfmenu_data2", PlayerData["Type"] )
- RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
- RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
- RunConsoleCommand( "acfmenu_data10", Data.Tracer )
-
- acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data["MaxTotalLength"],3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data["MaxTotalLength"],3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData["Type"]]["desc"]) --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
- acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m\\s") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA") --Proj muzzle penetration (Name, Desc)
-
-end
diff --git a/lua/ACF/Shared/Rounds/RoundAPHE.lua b/lua/ACF/Shared/Rounds/RoundAPHE.lua
deleted file mode 100644
index be629cd94..000000000
--- a/lua/ACF/Shared/Rounds/RoundAPHE.lua
+++ /dev/null
@@ -1,267 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundaphe.lua" )
-
-local DefTable = {}
- DefTable.type = "Ammo" --Tells the spawn menu what entity to spawn
- DefTable.name = "Armour Piercing Explosive (APHE)" --Human readable name
- DefTable.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
- DefTable.desc = "An armour piercing round with a cavity for High explosives. Less capable of defeating armour than plain Armour Piercing, but will explode after penetration"
- DefTable.netid = 5 --Unique ammotype ID for network transmission
-
- DefTable.create = function( Gun, BulletData ) ACF_APHECreate( Gun, BulletData ) end --Uses basic AP function
- DefTable.convert = function( Crate, Table ) local Result = ACF_APHEConvert( Crate, Table ) return Result end --Uses custom function
- DefTable.network = function( Crate, BulletData ) ACF_APHENetworkData( Crate, BulletData ) end
- DefTable.cratetxt = function( Crate ) local Result = ACF_APHECrateDisplay( Crate ) return Result end
-
- DefTable.propimpact = function( Bullet, Index, Target, HitNormal, HitPos , Bone ) local Result = ACF_APHEPropImpact( Bullet, Index, Target, HitNormal, HitPos , Bone ) return Result end --Uses basic AP function
- DefTable.worldimpact = function( Bullet, Index, HitPos, HitNormal ) local Result = ACF_APHEWorldImpact( Bullet, Index, HitPos, HitNormal ) return Result end --Uses basic AP function
- DefTable.endflight = function( Bullet, Index, HitPos, HitNormal ) ACF_APHEEndFlight( Bullet, Index, HitPos, HitNormal ) end --Uses basic AP function
-
- DefTable.endeffect = function( Effect, Bullet ) ACF_APHEEndEffect( Effect, Bullet ) end --Uses basic AP function
- DefTable.pierceeffect = function( Effect, Bullet ) ACF_APHEPierceEffect( Effect, Bullet ) end --Uses basic AP function
- DefTable.ricocheteffect = function( Effect, Bullet ) ACF_APHERicochetEffect( Effect, Bullet ) end --Uses basic AP function
-
- DefTable.guicreate = function( Panel, Table ) ACF_APHEGUICreate( Panel, Table ) end --References the function to use to draw that round menu, must use custom function
- DefTable.guiupdate = function( Panel, Table ) ACF_APHEGUIUpdate( Panel, Table ) end --References the function to use to update that round menu, must use custom function
-
-list.Set( "ACFRoundTypes", "APHE", DefTable ) --Set the round properties
-list.Set( "ACFIdRounds", DefTable.netid , "APHE" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
-
-ACF.AmmoBlacklist["APHE"] = { "MO", "MG" }
-
-AddCSLuaFile( "ACF/Shared/Rounds/RoundHE.lua" )
-
-function ACF_APHEConvert( Crate, PlayerData ) --Function to convert the player's slider data into the complete round data
-
- local Data = {}
- local ServerData = {}
- local GUIData = {}
-
- if not PlayerData["PropLength"] then PlayerData["PropLength"] = 0 end
- if not PlayerData["ProjLength"] then PlayerData["ProjLength"] = 0 end
- if not PlayerData["Data5"] then PlayerData["Data5"] = 0 end
- if not PlayerData["Data10"] then PlayerData["Data10"] = 0 end
-
- PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
-
- --Shell sturdiness calcs
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-PlayerData["Data5"],0)*7.9/1000 + math.min(PlayerData["Data5"],GUIData["ProjVolume"])*ACF.HEDensity/1000--Volume of the projectile as a cylinder - Volume of the filler * density of steel + Volume of the filler * density of TNT
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"], Data["LimitVel"] )
-
- local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data["FrAera"], Data["Caliber"], Data["ProjLength"] )
- GUIData["MinFillerVol"] = 0
- GUIData["MaxFillerVol"] = math.min(GUIData["ProjVolume"],MaxVol*0.9)
- GUIData["FillerVol"] = math.min(PlayerData["Data5"],GUIData["MaxFillerVol"])
- Data["FillerMass"] = GUIData["FillerVol"] * ACF.HEDensity/1000
-
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-GUIData["FillerVol"],0)*7.9/1000 + Data["FillerMass"]
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
-
- --Random bullshit left
- Data["ShovePower"] = 0.1
- Data["PenAera"] = Data["FrAera"]^ACF.PenAreaMod
- Data["DragCoef"] = ((Data["FrAera"]/10000)/Data["ProjMass"])
- Data["LimitVel"] = 700 --Most efficient penetration speed in m/s
- Data["KETransfert"] = 0.1 --Kinetic energy transfert to the target for movement purposes
- Data["Ricochet"] = 75 --Base ricochet angle
-
- Data["BoomPower"] = Data["PropMass"] + Data["FillerMass"]
-
- if SERVER then --Only the crates need this part
- ServerData["Id"] = PlayerData["Id"]
- ServerData["Type"] = PlayerData["Type"]
- return table.Merge(Data,ServerData)
- end
-
- if CLIENT then --Only tthe GUI needs this part
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"] - Data["FillerMass"], Data["LimitVel"] )
- GUIData["MaxPen"] = (Energy.Penetration/Data["PenAera"])*ACF.KEtoRHA
-
- GUIData["BlastRadius"] = Data["FillerMass"]^0.33*5*10
- local FragMass = Data["ProjMass"] - Data["FillerMass"]
- GUIData["Fragments"] = math.max(math.floor((Data["FillerMass"]/FragMass)*ACF.HEFrag),2)
- GUIData["FragMass"] = FragMass/GUIData["Fragments"]
- GUIData["FragVel"] = (Data["FillerMass"]*ACF.HEPower*1000/GUIData["FragMass"]/GUIData["Fragments"])^0.5
- return table.Merge(Data,GUIData)
- end
-
-end
-
-function ACF_APHECreate( Gun, BulletData )
-
- ACF_CreateBullet( BulletData )
-
-end
-
-function ACF_APHEPropImpact( Index, Bullet, Target, HitNormal, HitPos , Bone ) --Can be called from other round types
-
- if ACF_Check( Target ) then
-
- local Speed = Bullet["Flight"]:Length() / ACF.VelScale
- local Energy = ACF_Kinetic( Speed , Bullet["ProjMass"] - Bullet["FillerMass"], Bullet["LimitVel"] )
- local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
-
- if HitRes.Overkill > 0 then
- table.insert( Bullet["Filter"] , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
- ACF_Spall( HitPos , Bullet["Flight"] , Bullet["Filter"] , Energy.Kinetic*HitRes.Loss , Bullet["Caliber"] , Target.ACF.Armour , Bullet["Owner"] ) --Do some spalling
- Bullet["Flight"] = Bullet["Flight"]:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet["ProjMass"])^0.5 * 39.37
- return "Penetrated"
- elseif HitRes.Ricochet then
- return "Ricochet"
- else
- return false
- end
- else
- table.insert( Bullet["Filter"] , Target )
- return "Penetrated" end
-
-end
-
-function ACF_APHEWorldImpact( Index, Bullet, HitPos, HitNormal )
- local Energy = ACF_Kinetic( Bullet["Flight"]:Length() / ACF.VelScale, Bullet["ProjMass"] - Bullet["FillerMass"], Bullet["LimitVel"] )
- if ACF_PenetrateGround( Bullet, Energy, HitPos ) then
- return "Penetrated"
- else
- return false
- end
-
-end
-
-function ACF_APHEEndFlight( Index, Bullet, HitPos, HitNormal )
-
- ACF_HE( HitPos - Bullet["Flight"] * 0.015 , HitNormal , Bullet["FillerMass"] , Bullet["ProjMass"] - Bullet["FillerMass"] , Bullet["Owner"] )
- ACF_RemoveBullet( Index )
-
-end
-
---Ammocrate stuff
-function ACF_APHENetworkData( Crate, BulletData )
-
- Crate:SetNetworkedString("AmmoType","APHE")
- Crate:SetNetworkedString("AmmoID",BulletData["Id"])
- Crate:SetNetworkedInt("Caliber",BulletData["Caliber"])
- Crate:SetNetworkedInt("ProjMass",BulletData["ProjMass"])
- Crate:SetNetworkedInt("FillerMass",BulletData["FillerMass"])
- Crate:SetNetworkedInt("PropMass",BulletData["PropMass"])
- Crate:SetNetworkedInt("DragCoef",BulletData["DragCoef"])
- Crate:SetNetworkedInt("MuzzleVel",BulletData["MuzzleVel"])
- Crate:SetNetworkedInt("Tracer",BulletData["Tracer"])
-
-end
-
-function ACF_APHECrateDisplay( Crate )
-
- local Tracer = ""
- if Crate:GetNetworkedInt("Tracer") > 0 then Tracer = "-T" end
-
- local ProjMass = math.floor(Crate:GetNetworkedString("ProjMass")*1000)
- local PropMass = math.floor(Crate:GetNetworkedString("PropMass")*1000)
- local FillerMass = math.floor(Crate:GetNetworkedString("FillerMass")*1000)
-
- local txt = "Round Mass : "..ProjMass.." g\nPropellant : "..PropMass.." g\nHE Content : "..FillerMass.." g"
-
- return txt
-end
-
---Clientside effects
-function ACF_APHEDetEffect( Effect, Bullet )
-
- local Radius = (Bullet["FillerMass"])^0.33*8*39.37
- local Flash = EffectData()
- Flash:SetOrigin( Bullet["SimPos"] )
- Flash:SetNormal( Bullet["SimFlight"]:GetNormalized() )
- Flash:SetRadius( math.max( Radius, 1 ) )
- util.Effect( "ACF_Scaled_Explosion", Flash )
-
-end
-
-function ACF_APHEEndEffect( Effect, Bullet ) --Bullet stops here, do what you have to do clientside
-
- ACF_HEDetEffect( Effect, Bullet )
-
-end
-
-function ACF_APHEPierceEffect( Effect, Bullet ) --Bullet penetrated something, do what you have to clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Penetration", Spall )
-
-end
-
-function ACF_APHERicochetEffect( Effect, Bullet ) --Bullet ricocheted off something, do what you have to clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Ricochet", Spall )
-
-end
-
---GUI stuff after this
-function ACF_APHEGUICreate( Panel, Table )
-
- acfmenupanel:AmmoSelect( ACF.AmmoBlacklist["APHE"] )
-
- acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
-
- acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "HE Filler", "")--Hollow Point Cavity Slider (Name, Value, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
- acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
- acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
-
- ACF_APHEGUIUpdate( Panel, Table )
-
-end
-
-function ACF_APHEGUIUpdate( Panel, Table )
-
- local PlayerData = {}
- PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI
- PlayerData["Type"] = "APHE" --Hardcoded, match ACFRoundTypes table index
- PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider
- PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider
- PlayerData["Data5"] = acfmenupanel.AmmoData["FillerVol"]
- --PlayerData["Data6"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data7"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data8"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data9"] = acfmenupanel.AmmoData[Name] --Not used
- local Tracer = 0
- if acfmenupanel.AmmoData["Tracer"] then Tracer = 1 end
- PlayerData["Data10"] = Tracer --Tracer
-
- local Data = ACF_APHEConvert( Panel, PlayerData )
-
- RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData["Data"]["id"] )
- RunConsoleCommand( "acfmenu_data2", PlayerData["Type"] )
- RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
- RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
- RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
- RunConsoleCommand( "acfmenu_data10", Data.Tracer )
-
- acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data["MaxTotalLength"],3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data["MaxTotalLength"],3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "HE Filler Volume", "HE Filler Mass : "..(math.floor(Data["FillerMass"]*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData["Type"]]["desc"]) --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
- acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA") --Proj muzzle penetration (Name, Desc)
- acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/1000).." m\n") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
-
-end
diff --git a/lua/ACF/Shared/Rounds/RoundFunctions.lua b/lua/ACF/Shared/Rounds/RoundFunctions.lua
deleted file mode 100644
index bf31e0243..000000000
--- a/lua/ACF/Shared/Rounds/RoundFunctions.lua
+++ /dev/null
@@ -1,41 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundfunctions.lua" )
-
-function ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
-
- local BulletMax = ACF.Weapons["Guns"][PlayerData["Id"]]["round"]
- GUIData["MaxTotalLength"] = BulletMax["maxlength"]
-
- Data["Caliber"] = ACF.Weapons["Guns"][PlayerData["Id"]]["caliber"]
- Data["FrAera"] = 3.1416 * (Data["Caliber"]/2)^2
-
- Data["Tracer"] = 0
- if PlayerData["Data10"]*1 > 0 then --Check for tracer
- Data["Tracer"] = math.min(5/Data["Caliber"],2.5) --Tracer space calcs
- end
-
- local PropMax = (BulletMax["propweight"]*1000/ACF.PDensity) / Data["FrAera"] --Current casing absolute max propellant capacity
- local CurLength = (PlayerData["ProjLength"] + math.min(PlayerData["PropLength"],PropMax) + Data["Tracer"])
- GUIData["MinPropLength"] = 0.01
- GUIData["MaxPropLength"] = math.max(math.min(GUIData["MaxTotalLength"]-CurLength+PlayerData["PropLength"], PropMax),GUIData["MinPropLength"]) --Check if the desired prop lenght fits in the case and doesn't exceed the gun max
-
- GUIData["MinProjLength"] = Data["Caliber"]*1.5
- GUIData["MaxProjLength"] = math.max(GUIData["MaxTotalLength"]-CurLength+PlayerData["ProjLength"],GUIData["MinProjLength"]) --Check if the desired proj lenght fits in the case
-
- local Ratio = math.min( (GUIData["MaxTotalLength"] - Data["Tracer"])/(PlayerData["ProjLength"] + math.min(PlayerData["PropLength"],PropMax)) , 1 ) --This is to check the current ratio between elements if i need to clamp it
- Data["ProjLength"] = math.Clamp(PlayerData["ProjLength"]*Ratio,GUIData["MinProjLength"],GUIData["MaxProjLength"])
- Data["PropLength"] = math.Clamp(PlayerData["PropLength"]*Ratio,GUIData["MinPropLength"],GUIData["MaxPropLength"])
-
- Data["PropMass"] = Data["FrAera"] * (Data["PropLength"]*ACF.PDensity/1000) --Volume of the case as a cylinder * Powder density converted from g to kg
- GUIData["ProjVolume"] = Data["FrAera"] * Data["ProjLength"]
- Data["RoundVolume"] = Data["FrAera"] * (Data["ProjLength"] + Data["PropLength"])
-
- return PlayerData, Data, ServerData, GUIData
-end
-
-function ACF_RoundShellCapacity( Momentum, FrAera, Caliber, ProjLength )
- local MinWall = 0.2+((Momentum/FrAera)^0.7)/50 --The minimal shell wall thickness required to survive firing at the current energy level
- local Length = math.max(ProjLength-MinWall,0)
- local Radius = math.max((Caliber/2)-MinWall,0)
- local Volume = 3.1416*Radius^2 * Length
- return Volume, Length, Radius --Returning the cavity volume and the minimum wall thickness
-end
\ No newline at end of file
diff --git a/lua/ACF/Shared/Rounds/RoundHE.lua b/lua/ACF/Shared/Rounds/RoundHE.lua
deleted file mode 100644
index 3388eb928..000000000
--- a/lua/ACF/Shared/Rounds/RoundHE.lua
+++ /dev/null
@@ -1,257 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundhe.lua" )
-
-local DefTable = {}
- DefTable.type = "Ammo" --Tells the spawn menu what entity to spawn
- DefTable.name = "High Explosive (HE)" --Human readable name
- DefTable.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
- DefTable.desc = "A shell filled with explosives, detonating on impact"
- DefTable.netid = 2 --Unique ammotype ID for network transmission
-
- DefTable.create = function( Gun, BulletData ) ACF_HECreate( Gun, BulletData ) end
- DefTable.convert = function( Crate, Table ) local Result = ACF_HEConvert( Crate, Table ) return Result end
- DefTable.network = function( Crate, BulletData ) ACF_HENetworkData( Crate, BulletData ) end
- DefTable.cratetxt = function( Crate ) local Result = ACF_HECrateDisplay( Crate ) return Result end
-
- DefTable.propimpact = function( Bullet, Index, Target, HitNormal, HitPos , Bone ) local Result = ACF_HEPropImpact( Bullet, Index, Target, HitNormal, HitPos , Bone ) return Result end
- DefTable.worldimpact = function( Bullet, Index, HitPos, HitNormal ) local Result = ACF_HEWorldImpact( Bullet, Index, HitPos, HitNormal ) return Result end
- DefTable.endflight = function( Bullet, Index, HitPos, HitNormal ) ACF_HEEndFlight( Bullet, Index, HitPos, HitNormal ) end
-
- DefTable.endeffect = function( Effect, Bullet ) ACF_HEEndEffect( Effect, Bullet ) end
- DefTable.pierceeffect = function( Effect, Bullet ) ACF_HEPierceEffect( Effect, Bullet ) end
- DefTable.ricocheteffect = function( Effect, Bullet ) ACF_HERicochetEffect( Effect, Bullet ) end
-
- DefTable.guicreate = function( Panel, Table ) ACF_HEGUICreate( Panel, Table ) end --References the function to use to draw that round menu
- DefTable.guiupdate = function( Panel, Table ) ACF_HEGUIUpdate( Panel, Table ) end --References the function to use to update that round menu
-
-list.Set( "ACFRoundTypes", "HE", DefTable ) --Set the round properties
-list.Set( "ACFIdRounds", DefTable.netid , "HE" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
-
-function ACF_HEConvert( Crate, PlayerData ) --Function to convert the player's slider data into the complete round data
-
- local Data = {}
- local ServerData = {}
- local GUIData = {}
-
- if not PlayerData["PropLength"] then PlayerData["PropLength"] = 0 end
- if not PlayerData["ProjLength"] then PlayerData["ProjLength"] = 0 end
- if not PlayerData["Data5"] then PlayerData["Data5"] = 0 end
- if not PlayerData["Data10"] then PlayerData["Data10"] = 0 end
-
- PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
-
- --Shell sturdiness calcs
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-PlayerData["Data5"],0)*7.9/1000 + math.min(PlayerData["Data5"],GUIData["ProjVolume"])*ACF.HEDensity/1000--Volume of the projectile as a cylinder - Volume of the filler * density of steel + Volume of the filler * density of TNT
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"], Data["LimitVel"] )
-
- local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data["FrAera"], Data["Caliber"], Data["ProjLength"] )
- GUIData["MinFillerVol"] = 0
- GUIData["MaxFillerVol"] = math.min(GUIData["ProjVolume"],MaxVol)
- GUIData["FillerVol"] = math.min(PlayerData["Data5"],GUIData["MaxFillerVol"])
- Data["FillerMass"] = GUIData["FillerVol"] * ACF.HEDensity/1000
-
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-GUIData["FillerVol"],0)*7.9/1000 + Data["FillerMass"]
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
-
- --Random bullshit left
- Data["ShovePower"] = 0.1
- Data["PenAera"] = Data["FrAera"]^ACF.PenAreaMod
- Data["DragCoef"] = ((Data["FrAera"]/10000)/Data["ProjMass"])
- Data["LimitVel"] = 100 --Most efficient penetration speed in m/s
- Data["KETransfert"] = 0.1 --Kinetic energy transfert to the target for movement purposes
- Data["Ricochet"] = 60 --Base ricochet angle
-
- Data["BoomPower"] = Data["PropMass"] + Data["FillerMass"]
-
- if SERVER then --Only the crates need this part
- ServerData["Id"] = PlayerData["Id"]
- ServerData["Type"] = PlayerData["Type"]
- return table.Merge(Data,ServerData)
- end
-
- if CLIENT then --Only tthe GUI needs this part
- GUIData["BlastRadius"] = Data["FillerMass"]^0.33*5*10
- local FragMass = Data["ProjMass"] - Data["FillerMass"]
- GUIData["Fragments"] = math.max(math.floor((Data["FillerMass"]/FragMass)*ACF.HEFrag),2)
- GUIData["FragMass"] = FragMass/GUIData["Fragments"]
- GUIData["FragVel"] = (Data["FillerMass"]*ACF.HEPower*1000/GUIData["FragMass"]/GUIData["Fragments"])^0.5
- return table.Merge(Data,GUIData)
- end
-
-end
-
-function ACF_HECreate( Gun, BulletData )
-
- ACF_CreateBullet( BulletData )
-
-end
-
-function ACF_HEPropImpact( Index, Bullet, Target, HitNormal, HitPos , Bone ) --Can be called from other round types
-
- if ACF_Check( Target ) then
- local Speed = Bullet["Flight"]:Length() / ACF.VelScale
- local Energy = ACF_Kinetic( Speed , Bullet["ProjMass"] - Bullet["FillerMass"], Bullet["LimitVel"] )
- local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
- if HitRes.Ricochet then
- return "Ricochet"
- end
- end
- return false
-
-end
-
-function ACF_HEWorldImpact( Index, Bullet, HitPos, HitNormal )
-
- return false
-
-end
-
-function ACF_HEEndFlight( Index, Bullet, HitPos, HitNormal )
-
- ACF_HE( HitPos - Bullet["Flight"] * 0.015, HitNormal , Bullet["FillerMass"] , Bullet["ProjMass"] - Bullet["FillerMass"] , Bullet["Owner"] )
- ACF_RemoveBullet( Index )
-
-end
-
---Ammocrate stuff
-function ACF_HENetworkData( Crate, BulletData )
-
- Crate:SetNetworkedString("AmmoType","HE")
- Crate:SetNetworkedString("AmmoID",BulletData["Id"])
- Crate:SetNetworkedInt("Caliber",BulletData["Caliber"])
- Crate:SetNetworkedInt("ProjMass",BulletData["ProjMass"])
- Crate:SetNetworkedInt("FillerMass",BulletData["FillerMass"])
- Crate:SetNetworkedInt("PropMass",BulletData["PropMass"])
-
- Crate:SetNetworkedInt("DragCoef",BulletData["DragCoef"])
- Crate:SetNetworkedInt("MuzzleVel",BulletData["MuzzleVel"])
- Crate:SetNetworkedInt("Tracer",BulletData["Tracer"])
-
-end
-
-function ACF_HECrateDisplay( Crate )
-
-
- local Tracer = ""
- if Crate:GetNetworkedInt("Tracer") > 0 then Tracer = "-T" end
-
- local ProjMass = math.floor(Crate:GetNetworkedString("ProjMass")*1000)
- local PropMass = math.floor(Crate:GetNetworkedString("PropMass")*1000)
- local FillerMass = math.floor(Crate:GetNetworkedString("FillerMass")*1000)
-
- local txt = "Round Mass : "..ProjMass.." g\nPropellant : "..PropMass.." g\nHE Content : "..FillerMass.." g"
-
- return txt
-end
-
---Clientside effects
-function ACF_HEDetEffect( Effect, Bullet )
-
- local Radius = (Bullet.FillerMass)^0.33*8*39.37
- local Flash = EffectData()
- Flash:SetOrigin( Bullet.SimPos )
- Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
- Flash:SetRadius( math.max( Radius, 1 ) )
- util.Effect( "ACF_Scaled_Explosion", Flash )
-
-end
-
-function ACF_HEEndEffect( Effect, Bullet ) --Bullet stops here, do what you have to do clientside
-
- ACF_HEDetEffect( Effect, Bullet )
-
-end
-
-function ACF_HEPierceEffect( Effect, Bullet ) --Bullet penetrated something, do what you have to clientside
-
- local BulletEffect = {}
- BulletEffect.Num = 1
- BulletEffect.Src = Bullet.SimPos - Bullet.SimFlight:GetNormalized()
- BulletEffect.Dir = Bullet.SimFlight:GetNormalized()
- BulletEffect.Spread = Vector(0,0,0)
- BulletEffect.Tracer = 0
- BulletEffect.Force = 0
- BulletEffect.Damage = 0
- LocalPlayer():FireBullets(BulletEffect)
-
- util.Decal("ExplosiveGunshot", Bullet.SimPos + Bullet.SimFlight*10, Bullet.SimPos - Bullet.SimFlight*10)
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( math.max(((Bullet.RoundMass * (Bullet.SimFlight:Length()/39.37)^2)/2000)/10000,1) )
- util.Effect( "AP_Hit", Spall )
-
-end
-
-function ACF_HERicochetEffect( Effect, Bullet ) --Bullet ricocheted off something, do what you have to clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Ricochet", Spall )
-
-end
-
---GUI stuff after this
-function ACF_HEGUICreate( Panel, Table )
-
- acfmenupanel:AmmoSelect()
-
- acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
-
- acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "HE Filler", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
- acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
-
- ACF_HEGUIUpdate( Panel, Table )
-
-end
-
-function ACF_HEGUIUpdate( Panel, Table )
-
- local PlayerData = {}
- PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI
- PlayerData["Type"] = "HE" --Hardcoded, match ACFRoundTypes table index
- PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider
- PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider
- PlayerData["Data5"] = acfmenupanel.AmmoData["FillerVol"]
- --PlayerData["Data6"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data7"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data8"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data9"] = acfmenupanel.AmmoData[Name] --Not used
- local Tracer = 0
- if acfmenupanel.AmmoData["Tracer"] then Tracer = 1 end
- PlayerData["Data10"] = Tracer --Tracer
-
- local Data = ACF_HEConvert( Panel, PlayerData )
-
- RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData["Data"]["id"] )
- RunConsoleCommand( "acfmenu_data2", PlayerData["Type"] )
- RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
- RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
- RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
- RunConsoleCommand( "acfmenu_data10", Data.Tracer )
-
- acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data["MaxTotalLength"],3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data["MaxTotalLength"],3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "HE Filler Volume", "HE Filler Mass : "..(math.floor(Data["FillerMass"]*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData["Type"]]["desc"]) --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
- acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/1000).." m/n") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
-
-end
diff --git a/lua/ACF/Shared/Rounds/RoundHEAT.lua b/lua/ACF/Shared/Rounds/RoundHEAT.lua
deleted file mode 100644
index 391db4aa5..000000000
--- a/lua/ACF/Shared/Rounds/RoundHEAT.lua
+++ /dev/null
@@ -1,373 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundheat.lua" )
-
-local DefTable = {}
- DefTable.type = "Ammo" --Tells the spawn menu what entity to spawn
- DefTable.name = "High Explosive Anti-Tank (HEAT)" --Human readable name
- DefTable.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
- DefTable.desc = "A shaped charge explosive shell, detonating on impact and sending a stream of molten metal do penetrate armour along with normal, if reduced, explosive effects"
- DefTable.netid = 4 --Unique ammotype ID for network transmission
-
- DefTable.create = function( Gun, BulletData ) ACF_HEATCreate( Gun, BulletData ) end
- DefTable.convert = function( Crate, Table ) local Result = ACF_HEATConvert( Crate, Table ) return Result end
- DefTable.network = function( Crate, BulletData ) ACF_HEATNetworkData( Crate, BulletData ) end
- DefTable.cratetxt = function( Crate ) local Result = ACF_HEATCrateDisplay( Crate ) return Result end
-
- DefTable.propimpact = function( Bullet, Index, Target, HitNormal, HitPos , Bone ) local Result = ACF_HEATPropImpact( Bullet, Index, Target, HitNormal, HitPos , Bone ) return Result end
- DefTable.worldimpact = function( Bullet, Index, HitPos, HitNormal ) local Result = ACF_HEATWorldImpact( Bullet, Index, HitPos, HitNormal ) return Result end
- DefTable.endflight = function( Bullet, Index, HitPos, HitNormal ) ACF_HEATEndFlight( Bullet, Index, HitPos, HitNormal ) end
-
- DefTable.endeffect = function( Effect, Bullet ) ACF_HEATEndEffect( Effect, Bullet ) end
- DefTable.pierceeffect = function( Effect, Bullet ) ACF_HEATPierceEffect( Effect, Bullet ) end
- DefTable.ricocheteffect = function( Effect, Bullet ) ACF_HEATRicochetEffect( Effect, Bullet ) end
-
- DefTable.guicreate = function( Panel, Table ) ACF_HEATGUICreate( Panel, Table ) end --References the function to use to draw that round menu
- DefTable.guiupdate = function( Panel, Table ) ACF_HEATGUIUpdate( Panel, Table ) end --References the function to use to update that round menu
-
-list.Set( "ACFRoundTypes", "HEAT", DefTable ) --Set the round properties
-list.Set( "ACFIdRounds", DefTable.netid , "HEAT" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
-
-ACF.AmmoBlacklist["HEAT"] = { "MG", "HMG", "RAC", "AC" }
-
-function ACF_HEATConvert( Crate, PlayerData ) --Function to convert the player's slider data into the complete round data
-
- local Data = {}
- local ServerData = {}
- local GUIData = {}
-
- if not PlayerData["PropLength"] then PlayerData["PropLength"] = 0 end
- if not PlayerData["ProjLength"] then PlayerData["ProjLength"] = 0 end
- if not PlayerData["Data5"] then PlayerData["Data5"] = 0 end
- if not PlayerData["Data6"] then PlayerData["Data6"] = 0 end
- if not PlayerData["Data7"] then PlayerData["Data7"] = 0 end
- if not PlayerData["Data10"] then PlayerData["Data10"] = 0 end
-
- PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
-
- local ConeThick = Data["Caliber"]/50
- local ConeLength = 0
- local ConeAera = 0
- local AirVol = 0
- ConeLength, ConeAera, AirVol = ACF_HEATConeCalc( PlayerData["Data6"], Data["Caliber"]/2, PlayerData["ProjLength"] )
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-PlayerData["Data5"],0)*7.9/1000 + math.min(PlayerData["Data5"],GUIData["ProjVolume"])*ACF.HEDensity/1000 + ConeAera*ConeThick*7.9/1000 --Volume of the projectile as a cylinder - Volume of the filler - Volume of the crush cone * density of steel + Volume of the filler * density of TNT + Aera of the cone * thickness * density of steel
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"], Data["LimitVel"] )
-
- local MaxVol = 0
- local MaxLength = 0
- local MaxRadius = 0
- MaxVol, MaxLength, MaxRadius = ACF_RoundShellCapacity( Energy.Momentum, Data["FrAera"], Data["Caliber"], Data["ProjLength"] )
-
- GUIData["MinConeAng"] = 0
- GUIData["MaxConeAng"] = math.deg( math.atan((Data["ProjLength"] - ConeThick )/(Data["Caliber"]/2)) )
- GUIData["ConeAng"] = math.Clamp(PlayerData["Data6"]*1, GUIData["MinConeAng"], GUIData["MaxConeAng"])
- ConeLength, ConeAera, AirVol = ACF_HEATConeCalc( GUIData["ConeAng"], Data["Caliber"]/2, Data["ProjLength"] )
- local ConeVol = ConeAera * ConeThick
-
- GUIData["MinFillerVol"] = 0
- GUIData["MaxFillerVol"] = math.max(MaxVol - AirVol - ConeVol,GUIData["MinFillerVol"])
- GUIData["FillerVol"] = math.Clamp(PlayerData["Data5"]*1,GUIData["MinFillerVol"],GUIData["MaxFillerVol"])
-
- Data["FillerMass"] = GUIData["FillerVol"] * ACF.HEDensity/1000
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-GUIData["FillerVol"]- AirVol-ConeVol,0)*7.9/1000 + Data["FillerMass"] + ConeVol*7.9/1000
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"], Data["LimitVel"] )
-
- --Let's calculate the actual HEAT slug
- Data["SlugMass"] = ConeVol*7.9/1000
- local Rad = math.rad(GUIData["ConeAng"]/2)
- Data["SlugCaliber"] = Data["Caliber"] - Data["Caliber"] * (math.sin(Rad)*0.5+math.cos(Rad)*1.5)/2
- Data["SlugMV"] = ( Data["FillerMass"]/2 * ACF.HEPower * math.sin(math.rad(10+GUIData["ConeAng"])/2) /Data["SlugMass"])^ACF.HEATMVScale
-
- local SlugFrAera = 3.1416 * (Data["SlugCaliber"]/2)^2
- Data["SlugPenAera"] = SlugFrAera^ACF.PenAreaMod
- Data["SlugDragCoef"] = ((SlugFrAera/10000)/Data["SlugMass"])
- Data["SlugRicochet"] = 500 --Base ricochet angle (The HEAT slug shouldn't ricochet at all)
-
- Data["CasingMass"] = Data["ProjMass"] - Data["FillerMass"] - ConeVol*7.9/1000
-
- --Random bullshit left
- Data["ShovePower"] = 0.1
- Data["PenAera"] = Data["FrAera"]^ACF.PenAreaMod
- Data["DragCoef"] = ((Data["FrAera"]/10000)/Data["ProjMass"])
- Data["LimitVel"] = 100 --Most efficient penetration speed in m/s
- Data["KETransfert"] = 0.1 --Kinetic energy transfert to the target for movement purposes
- Data["Ricochet"] = 60 --Base ricochet angle
-
- Data["Detonated"] = false
- Data["BoomPower"] = Data["PropMass"] + Data["FillerMass"]
-
- if SERVER then --Only the crates need this part
- ServerData["Id"] = PlayerData["Id"]
- ServerData["Type"] = PlayerData["Type"]
- return table.Merge(Data,ServerData)
- end
-
- if CLIENT then --Only the GUI needs this part
- local SlugEnergy = ACF_Kinetic( Data["SlugMV"]*39.37 , Data["SlugMass"], 9999999 )
- GUIData["MaxPen"] = (SlugEnergy.Penetration/Data["SlugPenAera"])*ACF.KEtoRHA
- GUIData["BlastRadius"] = (Data["FillerMass"]/2)^0.33*5*10
- GUIData["Fragments"] = math.max(math.floor((Data["FillerMass"]/Data["CasingMass"])*ACF.HEFrag),2)
- GUIData["FragMass"] = Data["CasingMass"]/GUIData["Fragments"]
- GUIData["FragVel"] = (Data["FillerMass"]*ACF.HEPower*1000/Data["CasingMass"]/GUIData["Fragments"])^0.5
- return table.Merge(Data,GUIData)
- end
-
-end
-
-function ACF_HEATConeCalc( ConeAngle, Radius, Length )
-
- local ConeLength = math.tan(math.rad(ConeAngle))*Radius
- local ConeAera = 3.1416 * Radius * (Radius^2 + ConeLength^2)^0.5
- local ConeVol = (3.1416 * Radius^2 * ConeLength)/3
-
- return ConeLength, ConeAera, ConeVol
-end
-
-function ACF_HEATCreate( Gun, BulletData )
-
- ACF_CreateBullet( BulletData )
-
-end
-
-function ACF_HEATPropImpact( Index, Bullet, Target, HitNormal, HitPos , Bone ) --Can be called from other round types
-
- if ACF_Check( Target ) then
-
- if Bullet["Detonated"] then
-
- local Speed = Bullet["Flight"]:Length() / ACF.VelScale
- local Energy = ACF_Kinetic( Speed , Bullet["ProjMass"], 999999 )
- local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
-
- if HitRes.Overkill > 0 then
- table.insert( Bullet["Filter"] , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
- ACF_Spall( HitPos , Bullet["Flight"] , Bullet["Filter"] , Energy.Kinetic*HitRes.Loss , Bullet["Caliber"] , Target.ACF.Armour , Bullet["Owner"] ) --Do some spalling
- Bullet["Flight"] = Bullet["Flight"]:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet["ProjMass"])^0.5 * 39.37
- return "Penetrated"
- else
- return false
- end
-
- else
-
- local Speed = Bullet["Flight"]:Length() / ACF.VelScale
- local Energy = ACF_Kinetic( Speed , Bullet["ProjMass"] - Bullet["FillerMass"], Bullet["LimitVel"] )
- local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
-
- if HitRes.Ricochet then
- return "Ricochet"
- else
- ACF_HEATDetonate( Index, Bullet, HitPos, HitNormal )
- return "Penetrated"
- end
-
- end
- else
- table.insert( Bullet["Filter"] , Target )
- return "Penetrated"
- end
-
- return false
-
-end
-
-function ACF_HEATWorldImpact( Index, Bullet, HitPos, HitNormal )
-
- if not Bullet["Detonated"] then
- ACF_HEATDetonate( Index, Bullet, HitPos, HitNormal )
- return "Penetrated"
- end
-
- local Energy = ACF_Kinetic( Bullet["Flight"]:Length() / ACF.VelScale, Bullet["ProjMass"], 999999 )
- if ACF_PenetrateGround( Bullet, Energy, HitPos ) then
- return "Penetrated"
- else
- return false
- end
-
-end
-
-function ACF_HEATEndFlight( Index, Bullet, HitPos, HitNormal )
-
- ACF_RemoveBullet( Index )
-
-end
-
-function ACF_HEATDetonate( Index, Bullet, HitPos, HitNormal )
-
- ACF_HE( HitPos - Bullet["Flight"] * 0.015 , HitNormal , Bullet["FillerMass"]/2 , Bullet["CasingMass"] , Bullet["Owner"] )
-
- Bullet["Detonated"] = true
- Bullet["Pos"] = HitPos
- Bullet["Flight"] = Bullet["Flight"] + Bullet["Flight"]:GetNormalized() * Bullet["SlugMV"] * 39.37
- Bullet["DragCoef"] = Bullet["SlugDragCoef"]
-
- Bullet["ProjMass"] = Bullet["SlugMass"]
- Bullet["Caliber"] = Bullet["SlugCaliber"]
- Bullet["PenAera"] = Bullet["SlugPenAera"]
- Bullet["Ricochet"] = Bullet["SlugRicochet"]
-
- local DeltaTime = SysTime() - Bullet["LastThink"]
- Bullet["StartTrace"] = Bullet["Pos"] - Bullet["Flight"]:GetNormalized()*math.min(ACF.PhysMaxVel*DeltaTime,Bullet["FlightTime"]*Bullet["Flight"]:Length())
- Bullet["NextPos"] = Bullet["Pos"] + (Bullet["Flight"] * ACF.VelScale * DeltaTime) --Calculates the next shell position
-
-end
-
---Ammocrate stuff
-function ACF_HEATNetworkData( Crate, BulletData )
-
- Crate:SetNetworkedString("AmmoType","HEAT")
- Crate:SetNetworkedString("AmmoID",BulletData["Id"])
-
- Crate:SetNetworkedInt("Caliber",BulletData["Caliber"])
- Crate:SetNetworkedInt("ProjMass",BulletData["ProjMass"])
- Crate:SetNetworkedInt("FillerMass",BulletData["FillerMass"])
- Crate:SetNetworkedInt("PropMass",BulletData["PropMass"])
- Crate:SetNetworkedInt("DragCoef",BulletData["DragCoef"])
-
- Crate:SetNetworkedInt("SlugMass",BulletData["SlugMass"])
- Crate:SetNetworkedInt("SlugCaliber",BulletData["SlugCaliber"])
- Crate:SetNetworkedInt("SlugDragCoef",BulletData["SlugDragCoef"])
-
- Crate:SetNetworkedInt("MuzzleVel",BulletData["MuzzleVel"])
- Crate:SetNetworkedInt("Tracer",BulletData["Tracer"])
-
-end
-
-function ACF_HEATCrateDisplay( Crate )
-
- local Tracer = ""
- if Crate:GetNetworkedInt("Tracer") > 0 then Tracer = "-T" end
-
- local ProjMass = math.floor(Crate:GetNetworkedString("ProjMass")*1000)
- local PropMass = math.floor(Crate:GetNetworkedString("PropMass")*1000)
- local FillerMass = math.floor(Crate:GetNetworkedString("FillerMass")*1000)
-
- local txt = "Round Mass : "..ProjMass.." g\nPropellant : "..PropMass.." g\nHE Content : "..FillerMass.." g"
-
- return txt
-end
-
---Clientside effects
-function ACF_HEATDetEffect( Effect, Bullet )
-
- local Radius = (Bullet.FillerMass)^0.33*8*39.37
- local Flash = EffectData()
- Flash:SetOrigin( Bullet.SimPos )
- Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
- Flash:SetRadius( math.max( Radius, 1 ) )
- util.Effect( "ACF_HEAT_Explosion", Flash )
-
-end
-
-function ACF_HEATEndEffect( Effect, Bullet ) --Bullet stops here, do what you have to do clientside
-
- local Impact = EffectData()
- Impact:SetOrigin( Bullet.SimPos )
- Impact:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Impact:SetScale( Bullet.SimFlight:Length() )
- Impact:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Impact", Impact )
-
-end
-
-function ACF_HEATPierceEffect( Effect, Bullet ) --Bullet penetrated something, do what you have to clientside
-
- if Bullet.Detonated then
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Penetration", Spall )
-
- else
-
- ACF_HEATDetEffect( Effect, Bullet )
- Bullet.Detonated = true
- Effect:SetModel("models/Gibs/wood_gib01e.mdl")
-
- end
-
-end
-
-function ACF_HEATRicochetEffect( Effect, Bullet ) --Bullet ricocheted off something, do what you have to clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Ricochet", Spall )
-
-end
-
---GUI stuff after this
-function ACF_HEATGUICreate( Panel, Table )
-
- acfmenupanel:AmmoSelect( ACF.AmmoBlacklist["HEAT"] )
-
- acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
-
- --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "")
- acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "")
- acfmenupanel:AmmoSlider("ConeAng",0,0,1000,3, "HEAT Cone Angle", "")
- acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "Total HEAT Warhead volume", "")
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
- acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
-
- acfmenupanel:CPanelText("SlugDisplay", "") --HEAT Slug data (Name, Desc)
-
- ACF_HEATGUIUpdate( Panel, Table )
-
-end
-
-function ACF_HEATGUIUpdate( Panel, Table )
-
- local PlayerData = {}
- PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI
- PlayerData["Type"] = "HEAT" --Hardcoded, match ACFRoundTypes table index
- PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider
- PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider
- PlayerData["Data5"] = acfmenupanel.AmmoData["FillerVol"]
- PlayerData["Data6"] = acfmenupanel.AmmoData["ConeAng"] --Not used
- --PlayerData["Data7"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data8"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data9"] = acfmenupanel.AmmoData[Name] --Not used
- local Tracer = 0
- if acfmenupanel.AmmoData["Tracer"] then Tracer = 1 end
- PlayerData["Data10"] = Tracer --Tracer
-
- local Data = ACF_HEATConvert( Panel, PlayerData )
-
- RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData["Data"]["id"] )
- RunConsoleCommand( "acfmenu_data2", PlayerData["Type"] )
- RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
- RunConsoleCommand( "acfmenu_data4", Data.ProjLength )
- RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
- RunConsoleCommand( "acfmenu_data6", Data.ConeAng )
- RunConsoleCommand( "acfmenu_data10", Data.Tracer )
-
- acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data["MaxTotalLength"],3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data["MaxTotalLength"],3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ConeAng",Data.ConeAng,Data.MinConeAng,Data.MaxConeAng,0, "Crush Cone Angle", "") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "HE Filler Volume", "HE Filler Mass : "..(math.floor(Data["FillerMass"]*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData["Type"]]["desc"]) --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
- acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/1000).." m/n") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
-
- acfmenupanel:CPanelText("SlugDisplay", "Penetrator Mass : "..(math.floor(Data.SlugMass*10000)/10).." g \n Penetrator Caliber : "..(math.floor(Data.SlugCaliber*100)/10).." mm \n Penetrator Velocity : "..math.floor(Data.SlugMV).." m/s \n Penetrator Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n") --Proj muzzle penetration (Name, Desc)
-
-end
\ No newline at end of file
diff --git a/lua/ACF/Shared/Rounds/RoundHP.lua b/lua/ACF/Shared/Rounds/RoundHP.lua
deleted file mode 100644
index 06cc1eb04..000000000
--- a/lua/ACF/Shared/Rounds/RoundHP.lua
+++ /dev/null
@@ -1,170 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundhp.lua" )
-
-local DefTable = {}
- DefTable.type = "Ammo" --Tells the spawn menu what entity to spawn
- DefTable.name = "Hollow Point (HP)" --Human readable name
- DefTable.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
- DefTable.desc = "A solid shell with a soft point, meant to flatten against armour"
- DefTable.netid = 3 --Unique ammotype ID for network transmission
-
- DefTable.create = function( Gun, BulletData ) ACF_APCreate( Gun, BulletData ) end --Uses basic AP function
- DefTable.convert = function( Crate, Table ) local Result = ACF_HPConvert( Crate, Table ) return Result end --Uses custom function
- DefTable.network = function( Crate, BulletData ) ACF_HPNetworkData( Crate, BulletData ) end
- DefTable.cratetxt = function( Crate ) local Result = ACF_HPCrateDisplay( Crate ) return Result end
-
- DefTable.propimpact = function( Bullet, Index, Target, HitNormal, HitPos ) local Result = ACF_APPropImpact( Bullet, Index, Target, HitNormal, HitPos ) return Result end --Uses basic AP function
- DefTable.worldimpact = function( Bullet, Index, HitPos, HitNormal ) local Result = ACF_APWorldImpact( Bullet, Index, HitPos, HitNormal ) return Result end --Uses basic AP function
- DefTable.endflight = function( Bullet, Index, HitPos, HitNormal ) ACF_APEndFlight( Bullet, Index, HitPos, HitNormal ) end --Uses basic AP function
-
- DefTable.endeffect = function( Effect, Bullet ) ACF_APEndEffect( Effect, Bullet ) end --Uses basic AP function
- DefTable.pierceeffect = function( Effect, Bullet ) ACF_APPierceEffect( Effect, Bullet ) end --Uses basic AP function
- DefTable.ricocheteffect = function( Effect, Bullet ) ACF_APRicochetEffect( Effect, Bullet ) end --Uses basic AP function
-
- DefTable.guicreate = function( Panel, Table ) ACF_HPGUICreate( Panel, Table ) end --References the function to use to draw that round menu, must use custom function
- DefTable.guiupdate = function( Panel, Table ) ACF_HPGUIUpdate( Panel, Table ) end --References the function to use to update that round menu, must use custom function
-
-list.Set( "ACFRoundTypes", "HP", DefTable ) --Set the round properties
-list.Set( "ACFIdRounds", DefTable.netid , "HP" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
-
-
-function ACF_HPConvert( Crate, PlayerData ) --Function to convert the player's slider data into the complete round data
-
- local Data = {}
- local ServerData = {}
- local GUIData = {}
-
- if not PlayerData["PropLength"] then PlayerData["PropLength"] = 0 end
- if not PlayerData["ProjLength"] then PlayerData["ProjLength"] = 0 end
- if not PlayerData["Data5"] then PlayerData["Data5"] = 0 end
- if not PlayerData["Data10"] then PlayerData["Data10"] = 0 end
-
- PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
-
- --Shell sturdiness calcs
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-PlayerData["Data5"],0)*7.9/1000 --(Volume of the projectile as a cylinder - Volume of the cavity) * density of steel
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"], Data["LimitVel"] )
-
- local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data["FrAera"], Data["Caliber"], Data["ProjLength"] )
- GUIData["MinCavVol"] = 0
- GUIData["MaxCavVol"] = math.min(GUIData["ProjVolume"],MaxVol)
- Data["CavVol"] = math.min(PlayerData["Data5"],GUIData["MaxCavVol"])
-
- Data["ProjMass"] = ( (Data["FrAera"] * Data["ProjLength"]) - Data["CavVol"] )*7.9/1000 --Volume of the projectile as a cylinder * fraction missing due to hollow point (Data5) * density of steel
- local ExpRatio = (Data["CavVol"]/GUIData["ProjVolume"])
- Data["ShovePower"] = 0.2 + ExpRatio/2
- Data["ExpCaliber"] = Data["Caliber"] + ExpRatio*Data["ProjLength"]
- Data["PenAera"] = (3.1416 * Data["ExpCaliber"]/2)^2^ACF.PenAreaMod
- Data["DragCoef"] = ((Data["FrAera"]/10000)/Data["ProjMass"])
- Data["LimitVel"] = 400 --Most efficient penetration speed in m/s
- Data["KETransfert"] = 0.1 --Kinetic energy transfert to the target for movement purposes
- Data["Ricochet"] = 90 --Base ricochet angle
-
- Data["BoomPower"] = Data["PropMass"]
-
- if SERVER then --Only the crates need this part
- ServerData["Id"] = PlayerData["Id"]
- ServerData["Type"] = PlayerData["Type"]
- return table.Merge(Data,ServerData)
- end
-
- if CLIENT then --Only tthe GUI needs this part
- GUIData["MaxKETransfert"] = Energy.Kinetic*Data["ShovePower"]
- GUIData["MaxPen"] = (Energy.Penetration/Data["PenAera"])*ACF.KEtoRHA
- return table.Merge(Data,GUIData)
- end
-
-end
-
---Ammocrate stuff
-function ACF_HPNetworkData( Crate, BulletData )
-
- Crate:SetNetworkedString("AmmoType","HP")
- Crate:SetNetworkedString("AmmoID",BulletData["Id"])
-
- Crate:SetNetworkedInt("Caliber",BulletData["Caliber"])
- Crate:SetNetworkedInt("ProjMass",BulletData["ProjMass"])
- Crate:SetNetworkedInt("PropMass",BulletData["PropMass"])
- Crate:SetNetworkedInt("ExpCaliber",BulletData["ExpCaliber"])
-
- Crate:SetNetworkedInt("DragCoef",BulletData["DragCoef"])
- Crate:SetNetworkedInt("MuzzleVel",BulletData["MuzzleVel"])
- Crate:SetNetworkedInt("Tracer",BulletData["Tracer"])
-
-end
-
-function ACF_HPCrateDisplay( Crate )
-
- local Tracer = ""
- if Crate:GetNetworkedInt("Tracer") > 0 then Tracer = "-T" end
-
- local ProjMass = math.floor(Crate:GetNetworkedString("ProjMass")*1000)
- local PropMass = math.floor(Crate:GetNetworkedString("PropMass")*1000)
- local ExpCaliber = math.floor(Crate:GetNetworkedString("ExpCaliber")*1000)/100
-
- local txt = "Round Mass : "..ProjMass.." g\nPropellant : "..PropMass.." g\nExpanded Caliber : "..ExpCaliber.." mm"
-
- return txt
-end
-
---GUI stuff after this
-function ACF_HPGUICreate( Panel, Table )
-
- acfmenupanel:AmmoSelect()
-
- acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
-
- acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("CavVol",0,0,1000,2, "Hollow Point Length", "")--Hollow Point Cavity Slider (Name, Value, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
- acfmenupanel:CPanelText("KEDisplay", "") --Proj muzzle KE (Name, Desc)
-
- ACF_HPGUIUpdate( Panel, nil )
-
-end
-
-function ACF_HPGUIUpdate( Panel, Table )
-
- local PlayerData = {}
- PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI
- PlayerData["Type"] = "HP" --Hardcoded, match ACFRoundTypes table index
- PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider
- PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider
- PlayerData["Data5"] = acfmenupanel.AmmoData["CavVol"]
- --PlayerData["Data6"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data7"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data8"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data9"] = acfmenupanel.AmmoData[Name] --Not used
- local Tracer = 0
- if acfmenupanel.AmmoData["Tracer"] then Tracer = 1 end
- PlayerData["Data10"] = Tracer --Tracer
-
- local Data = ACF_HPConvert( Panel, PlayerData )
-
- RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData["Data"]["id"] )
- RunConsoleCommand( "acfmenu_data2", PlayerData["Type"] )
- RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
- RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
- RunConsoleCommand( "acfmenu_data5", Data.CavVol )
- RunConsoleCommand( "acfmenu_data10", Data.Tracer )
-
- acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data["MaxTotalLength"],3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data["MaxTotalLength"],3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoSlider("CavVol",Data.CavVol,Data.MinCavVol,Data.MaxCavVol,2, "Hollow Point cavity Volume", "Expanded caliber : "..(math.floor(Data.ExpCaliber*10)).." mm")--Hollow Point Cavity Slider (Name, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData["Type"]]["desc"]) --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
- acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA") --Proj muzzle penetration (Name, Desc)
- acfmenupanel:CPanelText("KEDisplay", "Kinetic Energy Transfered : "..math.floor(Data.MaxKETransfert).." KJ") --Proj muzzle KE (Name, Desc)
-
-end
\ No newline at end of file
diff --git a/lua/ACF/Shared/Rounds/RoundRefill.lua b/lua/ACF/Shared/Rounds/RoundRefill.lua
deleted file mode 100644
index 455f34277..000000000
--- a/lua/ACF/Shared/Rounds/RoundRefill.lua
+++ /dev/null
@@ -1,73 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundrefill.lua" )
-
-local DefTable = {}
- DefTable.type = "Ammo" --Tells the spawn menu what entity to spawn
- DefTable.name = "Refill" --Human readable name
- DefTable.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
- DefTable.desc = "Ammo Refill"
-
- DefTable.convert = function( Crate, Table ) local Result = ACF_RefillConvert( Crate, Table ) return Result end
- DefTable.network = function( Crate, BulletData ) ACF_RefillNetworkData( Crate, BulletData ) end
- DefTable.cratetxt = function( Crate ) local Result = ACF_RefillCrateDisplay( Crate ) return Result end
-
- DefTable.guicreate = function( Panel, Table ) ACF_RefillGUICreate( Panel, Table ) end --References the function to use to draw that round menu
- DefTable.guiupdate = function( Panel, Table ) ACF_RefillGUIUpdate( Panel, Table ) end --References the function to use to update that round menu
-
-list.Set( "ACFRoundTypes", "Refill", DefTable ) --Set the round properties
-
-function ACF_RefillConvert( Crate, PlayerData ) --Function to convert the player's slider data into the complete round data
-
- local BulletData = {}
- BulletData["Id"] = PlayerData["Id"]
- BulletData["Type"] = PlayerData["Type"]
-
- BulletData["Caliber"] = ACF.Weapons["Guns"][PlayerData["Id"]]["caliber"]
- BulletData["ProjMass"] = 0.5*7.9/100 --Volume of the projectile as a cylinder * streamline factor (Data5) * density of steel
- BulletData["PropMass"] = 0.5*ACF.PDensity/1000 --Volume of the case as a cylinder * Powder density converted from g to kg
- BulletData["RoundVolume"] = 1
-
- return BulletData
-
-end
-
---Ammocrate stuff
-function ACF_RefillNetworkData( Crate, BulletData )
-
- Crate:SetNetworkedString("AmmoType","Refill")
- Crate:SetNetworkedString("AmmoID",BulletData["Id"])
-
- Crate:SetNetworkedInt("Caliber",BulletData["Caliber"])
- Crate:SetNetworkedInt("ProjMass",BulletData["ProjMass"])
- Crate:SetNetworkedInt("FillerMass",BulletData["FillerMass"])
- Crate:SetNetworkedInt("PropMass",BulletData["PropMass"])
-
- Crate:SetNetworkedInt("DragCoef",BulletData["DragCoef"])
- Crate:SetNetworkedInt("MuzzleVel",BulletData["MuzzleVel"])
- Crate:SetNetworkedInt("Tracer",BulletData["Tracer"])
-
-end
-
-function ACF_RefillCrateDisplay( Crate )
-
- local txt = ""
-
- return txt
-end
-
---GUI stuff after this
-function ACF_RefillGUICreate( Panel, Table )
-
- acfmenupanel:AmmoSelect()
- acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
- ACF_RefillGUIUpdate( Panel, Table )
-
-end
-
-function ACF_RefillGUIUpdate( Panel, Table )
-
- RunConsoleCommand( "acfmenu_data1", acfmenupanel.CData["AmmoId"] )
- RunConsoleCommand( "acfmenu_data2", "Refill")
-
- acfmenupanel.CustomDisplay:PerformLayout()
-
-end
\ No newline at end of file
diff --git a/lua/ACF/Shared/Rounds/RoundSmoke.lua b/lua/ACF/Shared/Rounds/RoundSmoke.lua
deleted file mode 100644
index 4dd982803..000000000
--- a/lua/ACF/Shared/Rounds/RoundSmoke.lua
+++ /dev/null
@@ -1,258 +0,0 @@
-AddCSLuaFile( "acf/shared/rounds/roundsmoke.lua" )
-
-local DefTable = {}
- DefTable.type = "Ammo" --Tells the spawn menu what entity to spawn
- DefTable.name = "Smoke (SM)" --Human readable name
- DefTable.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
- DefTable.desc = "A shell filled white phosporous, detonating on impact. \n\n Can only be used in the 40mm Smoke Launcher"
- DefTable.netid = 6 --Unique ammotype ID for network transmission
-
- DefTable.create = function( Gun, BulletData ) ACF_SMCreate( Gun, BulletData ) end
- DefTable.convert = function( Crate, Table ) local Result = ACF_SMConvert( Crate, Table ) return Result end
- DefTable.network = function( Crate, BulletData ) ACF_SMNetworkData( Crate, BulletData ) end
- DefTable.cratetxt = function( Crate ) local Result = ACF_SMCrateDisplay( Crate ) return Result end
-
- DefTable.propimpact = function( Bullet, Index, Target, HitNormal, HitPos , Bone ) local Result = ACF_SMPropImpact( Bullet, Index, Target, HitNormal, HitPos , Bone ) return Result end
- DefTable.worldimpact = function( Bullet, Index, HitPos, HitNormal ) local Result = ACF_SMWorldImpact( Bullet, Index, HitPos, HitNormal ) return Result end
- DefTable.endflight = function( Bullet, Index, HitPos, HitNormal ) ACF_SMEndFlight( Bullet, Index, HitPos, HitNormal ) end
-
- DefTable.endeffect = function( Effect, Bullet ) ACF_SMEndEffect( Effect, Bullet ) end
- DefTable.pierceeffect = function( Effect, Bullet ) ACF_SMPierceEffect( Effect, Bullet ) end
- DefTable.ricocheteffect = function( Effect, Bullet ) ACF_SMRicochetEffect( Effect, Bullet ) end
-
- DefTable.guicreate = function( Panel, Table ) ACF_SMGUICreate( Panel, Table ) end --References the function to use to draw that round menu
- DefTable.guiupdate = function( Panel, Table ) ACF_SMGUIUpdate( Panel, Table ) end --References the function to use to update that round menu
-
-list.Set( "ACFRoundTypes", "SM", DefTable ) --Set the round properties
-list.Set( "ACFIdRounds", DefTable.netid , "SM" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
-ACF.AmmoBlacklist["SM"] = { "MO", "MG" , "HW", "C" , "GL" , "HMG" , "AL" , "AC" , "RAC" , }
-
-function ACF_SMConvert( Crate, PlayerData ) --Function to convert the player's slider data into the complete round data
-
- local Data = {}
- local ServerData = {}
- local GUIData = {}
-
- if not PlayerData["PropLength"] then PlayerData["PropLength"] = 0 end
- if not PlayerData["ProjLength"] then PlayerData["ProjLength"] = 0 end
- if not PlayerData["Data5"] then PlayerData["Data5"] = 0 end
- if not PlayerData["Data10"] then PlayerData["Data10"] = 0 end
-
- PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
-
- --Shell sturdiness calcs
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-PlayerData["Data5"],0)*7.9/1000 + math.min(PlayerData["Data5"],GUIData["ProjVolume"])*ACF.HEDensity/2000--Volume of the projectile as a cylinder - Volume of the filler * density of steel + Volume of the filler * density of TNT
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
- local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["ProjMass"], Data["LimitVel"] )
-
- local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data["FrAera"], Data["Caliber"], Data["ProjLength"] )
- GUIData["MinFillerVol"] = 0
- GUIData["MaxFillerVol"] = math.min(GUIData["ProjVolume"],MaxVol)
- GUIData["FillerVol"] = math.min(PlayerData["Data5"],GUIData["MaxFillerVol"])
- Data["FillerMass"] = GUIData["FillerVol"] * ACF.HEDensity/2000
-
- Data["ProjMass"] = math.max(GUIData["ProjVolume"]-GUIData["FillerVol"],0)*7.9/1000 + Data["FillerMass"]
- Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
-
- --Random bullshit left
- Data["ShovePower"] = 0.1
- Data["PenAera"] = Data["FrAera"]^ACF.PenAreaMod
- Data["DragCoef"] = ((Data["FrAera"]/10000)/Data["ProjMass"])
- Data["LimitVel"] = 100 --Most efficient penetration speed in m/s
- Data["KETransfert"] = 0.1 --Kinetic energy transfert to the target for movement purposes
- Data["Ricochet"] = 60 --Base ricochet angle
-
- Data["BoomPower"] = Data["PropMass"] + Data["FillerMass"]
-
- if SERVER then --Only the crates need this part
- ServerData["Id"] = PlayerData["Id"]
- ServerData["Type"] = PlayerData["Type"]
- return table.Merge(Data,ServerData)
- end
-
- if CLIENT then --Only tthe GUI needs this part
- GUIData["BlastRadius"] = Data["FillerMass"]^0
- local FragMass = Data["ProjMass"] - Data["FillerMass"]
- GUIData["Fragments"] = math.max(math.floor((Data["FillerMass"]/FragMass)*ACF.HEFrag),2)
- GUIData["FragMass"] = FragMass/GUIData["Fragments"]
- GUIData["FragVel"] = (Data["FillerMass"]*ACF.HEPower*1/GUIData["FragMass"]/GUIData["Fragments"])^0.5
- return table.Merge(Data,GUIData)
- end
-
-end
-
-function ACF_SMCreate( Gun, BulletData )
-
- ACF_CreateBullet( BulletData )
-
-end
-
-function ACF_SMPropImpact( Index, Bullet, Target, HitNormal, HitPos , Bone ) --Can be called from other round types
-
- if ACF_Check( Target ) then
- local Speed = Bullet["Flight"]:Length() / ACF.VelScale
- local Energy = ACF_Kinetic( Speed , Bullet["ProjMass"] - Bullet["FillerMass"], Bullet["LimitVel"] )
- local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
- if HitRes.Ricochet then
- return "Ricochet"
- end
- end
- return false
-
-end
-
-function ACF_SMWorldImpact( Index, Bullet, HitPos, HitNormal )
-
- return false
-
-end
-
-function ACF_SMEndFlight( Index, Bullet, HitPos, HitNormal )
-
- ACF_HE( HitPos - Bullet["Flight"] * 0.015, HitNormal , Bullet["FillerMass"] , Bullet["ProjMass"] - Bullet["FillerMass"] , Bullet["Owner"] )
- ACF_RemoveBullet( Index )
-
-end
-
---Ammocrate stuff
-function ACF_SMNetworkData( Crate, BulletData )
-
- Crate:SetNetworkedString("AmmoType","SM")
- Crate:SetNetworkedString("AmmoID",BulletData["Id"])
- Crate:SetNetworkedInt("Caliber",BulletData["Caliber"])
- Crate:SetNetworkedInt("ProjMass",BulletData["ProjMass"])
- Crate:SetNetworkedInt("FillerMass",BulletData["FillerMass"])
- Crate:SetNetworkedInt("PropMass",BulletData["PropMass"])
-
- Crate:SetNetworkedInt("DragCoef",BulletData["DragCoef"])
- Crate:SetNetworkedInt("MuzzleVel",BulletData["MuzzleVel"])
- Crate:SetNetworkedInt("Tracer",BulletData["Tracer"])
-
-end
-
-function ACF_SMCrateDisplay( Crate )
-
-
- local Tracer = ""
- if Crate:GetNetworkedInt("Tracer") > 0 then Tracer = "-T" end
-
- local ProjMass = math.floor(Crate:GetNetworkedString("ProjMass")*1000)
- local PropMass = math.floor(Crate:GetNetworkedString("PropMass")*1000)
- local FillerMass = math.floor(Crate:GetNetworkedString("FillerMass")*1000)
-
- local txt = "Round Mass : "..ProjMass.." g\nPropellant : "..PropMass.." g\nWP Content : "..FillerMass.." g"
-
- return txt
-end
-
---Clientside effects
-function ACF_SMDetEffect( Effect, Bullet )
-
- local Radius = (Bullet.FillerMass)^0.33*8*39.37
- local Flash = EffectData()
- Flash:SetOrigin( Bullet.SimPos )
- Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
- Flash:SetRadius( math.max( Radius, 1 ) )
- util.Effect( "ACF_Smoke", Flash )
-
-end
-
-function ACF_SMEndEffect( Effect, Bullet ) --Bullet stops here, do what you have to do clientside
-
- ACF_SMDetEffect( Effect, Bullet )
-
-end
-
-function ACF_SMPierceEffect( Effect, Bullet ) --Bullet penetrated something, do what you have to clientside
-
- local BulletEffect = {}
- BulletEffect.Num = 1
- BulletEffect.Src = Bullet.SimPos - Bullet.SimFlight:GetNormalized()
- BulletEffect.Dir = Bullet.SimFlight:GetNormalized()
- BulletEffect.Spread = Vector(0,0,0)
- BulletEffect.Tracer = 0
- BulletEffect.Force = 0
- BulletEffect.Damage = 0
- LocalPlayer():FireBullets(BulletEffect)
-
- util.Decal("ExplosiveGunshot", Bullet.SimPos + Bullet.SimFlight*10, Bullet.SimPos - Bullet.SimFlight*10)
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( math.max(((Bullet.RoundMass * (Bullet.SimFlight:Length()/39.37)^2)/2000)/10000,1) )
- util.Effect( "AP_Hit", Spall )
-
-end
-
-function ACF_SMRicochetEffect( Effect, Bullet ) --Bullet ricocheted off something, do what you have to clientside
-
- local Spall = EffectData()
- Spall:SetOrigin( Bullet.SimPos )
- Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
- Spall:SetScale( Bullet.SimFlight:Length() )
- Spall:SetMagnitude( Bullet.RoundMass )
- util.Effect( "ACF_AP_Ricochet", Spall )
-
-end
-
---GUI stuff after this
-function ACF_SMGUICreate( Panel, Table )
-
- acfmenupanel:AmmoSelect()
-
- acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
-
- acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "WP Filler", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
- acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
- acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
-
- ACF_SMGUIUpdate( Panel, Table )
-
-end
-
-function ACF_SMGUIUpdate( Panel, Table )
-
- local PlayerData = {}
- PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI
- PlayerData["Type"] = "SM" --Hardcoded, match ACFRoundTypes table index
- PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider
- PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider
- PlayerData["Data5"] = acfmenupanel.AmmoData["FillerVol"]
- --PlayerData["Data6"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data7"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data8"] = acfmenupanel.AmmoData[Name] --Not used
- --PlayerData["Data9"] = acfmenupanel.AmmoData[Name] --Not used
- local Tracer = 0
- if acfmenupanel.AmmoData["Tracer"] then Tracer = 1 end
- PlayerData["Data10"] = Tracer --Tracer
-
- local Data = ACF_SMConvert( Panel, PlayerData )
-
- RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData["Data"]["id"] )
- RunConsoleCommand( "acfmenu_data2", PlayerData["Type"] )
- RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
- RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
- RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
- RunConsoleCommand( "acfmenu_data10", Data.Tracer )
-
- acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data["MaxTotalLength"],3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data["MaxTotalLength"],3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
- acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "WP Filler Volume", "WP Filler Mass : "..(math.floor(Data["FillerMass"]*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
-
- acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
-
- acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData["Type"]]["desc"]) --Description (Name, Desc)
- acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
- acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
- ---acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/1000).." m\n") --Proj muzzle velocity (Name, Desc)
- ---acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." ---g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
-
-end
diff --git a/lua/acf/client/cl_acfballistics.lua b/lua/acf/client/cl_acfballistics.lua
new file mode 100644
index 000000000..1f68839ca
--- /dev/null
+++ b/lua/acf/client/cl_acfballistics.lua
@@ -0,0 +1,29 @@
+ACF.BulletEffect = {}
+
+function ACF_ManageBulletEffects()
+
+ for Index,Bullet in pairs(ACF.BulletEffect) do
+ ACF_SimBulletFlight( Bullet, Index ) --This is the bullet entry in the table, the omnipresent Index var refers to this
+ end
+
+end
+hook.Add("Think", "ACF_ManageBulletEffects", ACF_ManageBulletEffects)
+
+function ACF_SimBulletFlight( Bullet, Index )
+
+ --local DeltaTime = ACF.CurTime - Bullet.LastThink
+ local DeltaTime = CurTime() - Bullet.LastThink --intentionally not using cached curtime value
+
+ local Drag = Bullet.SimFlight:GetNormalized() * (Bullet.DragCoef * Bullet.SimFlight:Length()^2)/ACF.DragDiv
+ --print(Drag)
+ --debugoverlay.Cross(Bullet.SimPos,3,15,Color(255,255,255,32), true)
+ Bullet.SimPosLast = Bullet.SimPos
+ Bullet.SimPos = Bullet.SimPos + (Bullet.SimFlight * ACF.VelScale * DeltaTime) --Calculates the next shell position
+ Bullet.SimFlight = Bullet.SimFlight + (Bullet.Accel - Drag)*DeltaTime --Calculates the next shell vector
+
+ if Bullet and Bullet.Effect:IsValid() then
+ Bullet.Effect:ApplyMovement( Bullet )
+ end
+ Bullet.LastThink = CurTime() --ACF.CurTime --intentionally not using cached curtime value
+
+end
diff --git a/lua/acf/client/cl_acfmenu_gui.lua b/lua/acf/client/cl_acfmenu_gui.lua
new file mode 100644
index 000000000..e8d450835
--- /dev/null
+++ b/lua/acf/client/cl_acfmenu_gui.lua
@@ -0,0 +1,482 @@
+
+function PANEL:Init( )
+
+ acfmenupanel = self.Panel
+
+ // height
+
+
+ self:SetTall( surface.ScreenHeight() - 120 )
+
+ //Weapon Select
+
+ self.WeaponSelect = vgui.Create( "DTree", self )
+
+ self.WeaponData = ACF.Weapons
+
+ local Classes = list.Get("ACFClasses")
+ self.Classes = {}
+ for ID,Table in pairs(Classes) do
+ self.Classes[ID] = {}
+ for ClassID,Class in pairs(Table) do
+ Class.id = ClassID
+ table.insert(self.Classes[ID], Class)
+ end
+ table.sort(self.Classes[ID], function(a,b) return a.id < b.id end )
+ end
+
+ local WeaponDisplay = list.Get("ACFEnts")
+ self.WeaponDisplay = {}
+ for ID,Table in pairs(WeaponDisplay) do
+ self.WeaponDisplay[ID] = {}
+ for EntID,Data in pairs(Table) do
+ table.insert(self.WeaponDisplay[ID], Data)
+ end
+
+ if ID == "Guns" then
+ table.sort(self.WeaponDisplay[ID], function(a,b) if a.gunclass == b.gunclass then return a.caliber < b.caliber else return a.gunclass < b.gunclass end end)
+ else
+ table.sort(self.WeaponDisplay[ID], function(a,b) return a.id < b.id end )
+ end
+
+ end
+
+ local HomeNode = self.WeaponSelect:AddNode( "ACF Home" )
+ HomeNode.mytable = {}
+ HomeNode.mytable.guicreate = (function( Panel, Table ) ACFHomeGUICreate( Table ) end or nil)
+ HomeNode.mytable.guiupdate = (function( Panel, Table ) ACFHomeGUIUpdate( Table ) end or nil)
+ function HomeNode:DoClick()
+ acfmenupanel:UpdateDisplay(self.mytable)
+ end
+ HomeNode.Icon:SetImage( "icon16/newspaper.png" )
+
+ local RoundAttribs = list.Get("ACFRoundTypes")
+ self.RoundAttribs = {}
+ for ID,Table in pairs(RoundAttribs) do
+ Table.id = ID
+ table.insert(self.RoundAttribs, Table)
+ end
+ table.sort(self.RoundAttribs, function(a,b) return a.id < b.id end )
+
+ local Guns = self.WeaponSelect:AddNode( "Guns" )
+ for ClassID,Class in pairs(self.Classes["GunClass"]) do
+
+ local SubNode = Guns:AddNode( Class.name or "No Name" )
+
+ for Type, Ent in pairs(self.WeaponDisplay["Guns"]) do
+ if Ent.gunclass == Class.id then
+ local EndNode = SubNode:AddNode( Ent.name or "No Name" )
+ EndNode.mytable = Ent
+ function EndNode:DoClick()
+ RunConsoleCommand( "acfmenu_type", self.mytable.type )
+ acfmenupanel:UpdateDisplay( self.mytable )
+ end
+ EndNode.Icon:SetImage( "icon16/newspaper.png" )
+ end
+ end
+
+ end
+
+ local Ammo = self.WeaponSelect:AddNode( "Ammo" )
+ for AmmoID,AmmoTable in pairs(self.RoundAttribs) do
+
+ local EndNode = Ammo:AddNode( AmmoTable.name or "No Name" )
+ EndNode.mytable = AmmoTable
+ function EndNode:DoClick()
+ RunConsoleCommand( "acfmenu_type", self.mytable.type )
+ acfmenupanel:UpdateDisplay( self.mytable )
+ end
+ EndNode.Icon:SetImage( "icon16/newspaper.png" )
+
+ end
+
+ local Mobility = self.WeaponSelect:AddNode( "Mobility" )
+ local Engines = Mobility:AddNode( "Engines" )
+ local Gearboxes = Mobility:AddNode( "Gearboxes" )
+ local FuelTanks = Mobility:AddNode( "Fuel Tanks" )
+ local EngineSubcats = {}
+ for _, MobilityTable in pairs(self.WeaponDisplay["Mobility"]) do
+ NodeAdd = Mobility
+ if( MobilityTable.ent == "acf_engine" ) then
+ NodeAdd = Engines
+ elseif ( MobilityTable.ent == "acf_gearbox" ) then
+ NodeAdd = Gearboxes
+ elseif ( MobilityTable.ent == "acf_fueltank" ) then
+ NodeAdd = FuelTanks
+ end
+ if((EngineSubcats["misce"] == nil) and (EngineSubcats["miscg"] == nil)) then
+ EngineSubcats["misce"] = Engines:AddNode( "Miscellaneous" )
+ EngineSubcats["miscg"] = Gearboxes:AddNode( "Miscellaneous" )
+ end
+ if(MobilityTable.category) then
+ if(!EngineSubcats[MobilityTable.category]) then
+ EngineSubcats[MobilityTable.category] = NodeAdd:AddNode( MobilityTable.category )
+ end
+ end
+ end
+
+ for MobilityID,MobilityTable in pairs(self.WeaponDisplay["Mobility"]) do
+
+ local NodeAdd = Mobility
+ if MobilityTable.ent == "acf_engine" then
+ NodeAdd = Engines
+ if(MobilityTable.category) then
+ NodeAdd = EngineSubcats[MobilityTable.category]
+ else
+ NodeAdd = EngineSubcats["misce"]
+ end
+ elseif MobilityTable.ent == "acf_gearbox" then
+ NodeAdd = Gearboxes
+ if(MobilityTable.category) then
+ NodeAdd = EngineSubcats[MobilityTable.category]
+ else
+ NodeAdd = EngineSubcats["miscg"]
+ end
+ elseif MobilityTable.ent == "acf_fueltank" then
+ NodeAdd = FuelTanks
+ if (MobilityTable.category) then
+ NodeAdd = EngineSubcats[MobilityTable.category]
+ end
+ end
+
+ local EndNode = NodeAdd:AddNode( MobilityTable.name or "No Name" )
+ EndNode.mytable = MobilityTable
+ function EndNode:DoClick()
+ RunConsoleCommand( "acfmenu_type", self.mytable.type )
+ acfmenupanel:UpdateDisplay( self.mytable )
+ end
+ EndNode.Icon:SetImage( "icon16/newspaper.png" )
+
+ end
+
+
+
+ /*local Missiles = self.WeaponSelect:AddNode( "Missiles" )
+ for MisID, MisTable in pairs(self.WeaponDisplay["Missiles"]) do
+
+ local EndNode = Missiles:AddNode( MisTable.name or "No Name" )
+
+ EndNode.mytable = MisTable
+ function EndNode:DoClick()
+ RunConsoleCommand( "acfmenu_type", self.mytable.type )
+ acfmenupanel:UpdateDisplay( self.mytable )
+ end
+
+ EndNode.Icon:SetImage( "icon16/newspaper.png")
+
+ end*/
+ -- local Sensors = self.WeaponSelect:AddNode( "Sensors" )
+ -- for SensorsID,SensorsTable in pairs(self.WeaponDisplay["Sensors"]) do
+
+ -- local EndNode = Sensors:AddNode( SensorsTable.name or "No Name" )
+ -- EndNode.mytable = SensorsTable
+ -- function EndNode:DoClick()
+ -- RunConsoleCommand( "acfmenu_type", self.mytable.type )
+ -- acfmenupanel:UpdateDisplay( self.mytable )
+ -- end
+ -- EndNode.Icon:SetImage( "icon16/newspaper.png" )
+
+ -- end
+
+end
+
+/*------------------------------------
+ Think
+------------------------------------*/
+function PANEL:Think( )
+
+end
+
+function PANEL:UpdateDisplay( Table )
+
+ RunConsoleCommand( "acfmenu_id", Table.id or 0 )
+
+ --If a previous display exists, erase it
+ if ( acfmenupanel.CustomDisplay ) then
+ acfmenupanel.CustomDisplay:Clear(true)
+ acfmenupanel.CustomDisplay = nil
+ acfmenupanel.CData = nil
+ end
+ --Create the space to display the custom data
+ acfmenupanel.CustomDisplay = vgui.Create( "DPanelList", acfmenupanel )
+ acfmenupanel.CustomDisplay:SetSpacing( 10 )
+ acfmenupanel.CustomDisplay:EnableHorizontal( false )
+ acfmenupanel.CustomDisplay:EnableVerticalScrollbar( false )
+ acfmenupanel.CustomDisplay:SetSize( acfmenupanel:GetWide(), acfmenupanel:GetTall() )
+
+ if not acfmenupanel["CData"] then
+ --Create a table for the display to store data
+ acfmenupanel["CData"] = {}
+ end
+
+ acfmenupanel.CreateAttribs = Table.guicreate
+ acfmenupanel.UpdateAttribs = Table.guiupdate
+ acfmenupanel:CreateAttribs( Table )
+
+ acfmenupanel:PerformLayout()
+
+end
+
+function PANEL:CreateAttribs( Table )
+ --You overwrite this with your own function, defined in the ammo definition file, so each ammotype creates it's own menu
+end
+
+function PANEL:UpdateAttribs( Table )
+ --You overwrite this with your own function, defined in the ammo definition file, so each ammotype creates it's own menu
+end
+
+function PANEL:PerformLayout()
+
+ --Starting positions
+ local vspacing = 10
+ local ypos = 0
+
+ --Selection Tree panel
+ acfmenupanel.WeaponSelect:SetPos( 0, ypos )
+ acfmenupanel.WeaponSelect:SetSize( acfmenupanel:GetWide(), ScrH()*0.4 )
+ ypos = acfmenupanel.WeaponSelect.Y + acfmenupanel.WeaponSelect:GetTall() + vspacing
+
+ if acfmenupanel.CustomDisplay then
+ --Custom panel
+ acfmenupanel.CustomDisplay:SetPos( 0, ypos )
+ acfmenupanel.CustomDisplay:SetSize( acfmenupanel:GetWide(), acfmenupanel:GetTall() - acfmenupanel.WeaponSelect:GetTall() - 10 )
+ ypos = acfmenupanel.CustomDisplay.Y + acfmenupanel.CustomDisplay:GetTall() + vspacing
+ end
+
+end
+
+function ACFHomeGUICreate( Table )
+
+ if not acfmenupanel.CustomDisplay then return end
+ --start version
+
+ acfmenupanel["CData"]["VersionInit"] = vgui.Create( "DLabel" )
+ versiontext = "Version\n\n".."Git Version: "..ACF.CurrentVersion.."\nCurrent Version: "..ACF.Version
+ acfmenupanel["CData"]["VersionInit"]:SetText(versiontext)
+ acfmenupanel["CData"]["VersionInit"]:SetDark( true )
+ acfmenupanel["CData"]["VersionInit"]:SizeToContents()
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"]["VersionInit"] )
+
+
+ acfmenupanel["CData"]["VersionText"] = vgui.Create( "DLabel" )
+
+ local color
+ local versionstring
+ if ACF.Version >= ACF.CurrentVersion then
+ versionstring = "Up To Date"
+ color = Color(0,225,0,255)
+ else
+ versionstring = "Out Of Date"
+ color = Color(225,0,0,255)
+
+ end
+
+ acfmenupanel["CData"]["VersionText"]:SetText("ACF Is "..versionstring.."!\n\n\n\n")
+ acfmenupanel["CData"]["VersionText"]:SetDark( true )
+ acfmenupanel["CData"]["VersionText"]:SetColor(color)
+ acfmenupanel["CData"]["VersionText"]:SizeToContents()
+
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"]["VersionText"] )
+ -- end version
+
+ acfmenupanel:CPanelText("Header", "Changelog")
+
+ if acfmenupanel.Changelog then
+ acfmenupanel["CData"]["Changelist"] = vgui.Create( "DTree" )
+ for Rev,Changes in pairs(acfmenupanel.Changelog) do
+
+ local Node = acfmenupanel["CData"]["Changelist"]:AddNode( "Rev "..Rev )
+ Node.mytable = {}
+ Node.mytable["rev"] = Rev
+ function Node:DoClick()
+ acfmenupanel:UpdateAttribs( Node.mytable )
+ end
+ Node.Icon:SetImage( "icon16/newspaper.png" )
+
+ end
+ acfmenupanel.CData.Changelist:SetSize( acfmenupanel.CustomDisplay:GetWide(), 60 )
+
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"]["Changelist"] )
+
+ acfmenupanel.CustomDisplay:PerformLayout()
+
+ acfmenupanel:UpdateAttribs( {rev = table.maxn(acfmenupanel.Changelog)} )
+ end
+
+end
+
+function ACFHomeGUIUpdate( Table )
+
+ acfmenupanel:CPanelText("Changelog", acfmenupanel.Changelog[Table["rev"]])
+ acfmenupanel.CustomDisplay:PerformLayout()
+
+ local color
+ local versionstring
+ if ACF.Version >= ACF.CurrentVersion then
+ versionstring = "Up To Date"
+ color = Color(0,225,0,255)
+ else
+ versionstring = "Out Of Date"
+ color = Color(225,0,0,255)
+
+ end
+
+ acfmenupanel["CData"]["VersionText"]:SetText("ACF Is "..versionstring.."!\n\n\n\n")
+ acfmenupanel["CData"]["VersionText"]:SetDark( true )
+ acfmenupanel["CData"]["VersionText"]:SetColor(color)
+ acfmenupanel["CData"]["VersionText"]:SizeToContents()
+
+end
+
+function ACFChangelogHTTPCallBack(contents , size)
+ local Temp = string.Explode( "*", contents )
+
+ acfmenupanel.Changelog = {}
+ for Key,String in pairs(Temp) do
+ acfmenupanel.Changelog[tonumber(string.sub(String,2,4))] = string.Trim(string.sub(String, 5))
+ end
+ table.SortByKey(acfmenupanel.Changelog,true)
+
+ local Table = {}
+ Table.guicreate = (function( Panel, Table ) ACFHomeGUICreate( Table ) end or nil)
+ Table.guiupdate = (function( Panel, Table ) ACFHomeGUIUpdate( Table ) end or nil)
+ acfmenupanel:UpdateDisplay( Table )
+
+end
+http.Fetch("http://raw.github.com/nrlulz/ACF/master/changelog.txt", ACFChangelogHTTPCallBack, function() end)
+
+function PANEL:AmmoSelect( Blacklist )
+
+ if not acfmenupanel.CustomDisplay then return end
+ if not Blacklist then Blacklist = {} end
+
+ if not acfmenupanel.AmmoData then
+ acfmenupanel.AmmoData = {}
+ acfmenupanel.AmmoData["Id"] = "Ammo2x4x4"
+ acfmenupanel.AmmoData["Type"] = "Ammo"
+ acfmenupanel.AmmoData["Data"] = acfmenupanel.WeaponData["Guns"]["12.7mmMG"]["round"]
+ end
+
+ --Creating the ammo crate selection
+ acfmenupanel.CData.CrateSelect = vgui.Create( "DComboBox", acfmenupanel.CustomDisplay ) --Every display and slider is placed in the Round table so it gets trashed when selecting a new round type
+ acfmenupanel.CData.CrateSelect:SetSize(100, 30)
+ for Key, Value in pairs( acfmenupanel.WeaponDisplay["Ammo"] ) do
+ acfmenupanel.CData.CrateSelect:AddChoice( Value.id , Key )
+ end
+ acfmenupanel.CData.CrateSelect.OnSelect = function( index , value , data )
+ RunConsoleCommand( "acfmenu_id", data )
+ acfmenupanel.AmmoData["Id"] = data
+ self:UpdateAttribs()
+ end
+ acfmenupanel.CData.CrateSelect:SetText(acfmenupanel.AmmoData["Id"])
+ RunConsoleCommand( "acfmenu_id", acfmenupanel.AmmoData["Id"] )
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.CrateSelect )
+
+ --Create the caliber selection display
+ acfmenupanel.CData.CaliberSelect = vgui.Create( "DComboBox", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.CaliberSelect:SetSize(100, 30)
+ for Key, Value in pairs( acfmenupanel.WeaponDisplay["Guns"] ) do
+ if( !table.HasValue( Blacklist, Value.gunclass ) ) then
+ acfmenupanel.CData.CaliberSelect:AddChoice( Value.id , Key )
+ end
+ end
+ acfmenupanel.CData.CaliberSelect.OnSelect = function( index , value , data )
+ acfmenupanel.AmmoData["Data"] = acfmenupanel.WeaponData["Guns"][data]["round"]
+ self:UpdateAttribs()
+ self:UpdateAttribs() --Note : this is intentional
+ end
+ acfmenupanel.CData.CaliberSelect:SetText(acfmenupanel.AmmoData["Data"]["id"])
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.CaliberSelect )
+
+end
+
+function PANEL:AmmoSlider(Name, Value, Min, Max, Decimals, Title, Desc) --Variable name in the table, Value, Min value, Max Value, slider text title, slider decimeals, description text below slider
+
+ if not acfmenupanel["CData"][Name] then
+ acfmenupanel["CData"][Name] = vgui.Create( "DNumSlider", acfmenupanel.CustomDisplay )
+ acfmenupanel["CData"][Name].Label:SetSize( 0 ) --Note : this is intentional
+ acfmenupanel["CData"][Name]:SetTall( 50 ) -- make the slider taller to fit the new label
+ acfmenupanel["CData"][Name]:SetMin( 0 )
+ acfmenupanel["CData"][Name]:SetMax( 1000 )
+ acfmenupanel["CData"][Name]:SetDecimals( Decimals )
+ acfmenupanel["CData"][Name.."_label"] = vgui.Create( "DLabel", acfmenupanel["CData"][Name]) -- recreating the label
+ acfmenupanel["CData"][Name.."_label"]:SetPos( 0,0 )
+ acfmenupanel["CData"][Name.."_label"]:SetText( Title )
+ acfmenupanel["CData"][Name.."_label"]:SizeToContents()
+ acfmenupanel["CData"][Name.."_label"]:SetDark( true )
+ if acfmenupanel.AmmoData[Name] then
+ acfmenupanel["CData"][Name]:SetValue(acfmenupanel.AmmoData[Name])
+ end
+ acfmenupanel["CData"][Name].OnValueChanged = function( slider, val )
+ if acfmenupanel.AmmoData[Name] != val then
+ acfmenupanel.AmmoData[Name] = val
+ self:UpdateAttribs( Name )
+ end
+ end
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name] )
+ end
+ acfmenupanel["CData"][Name]:SetMin( Min )
+ acfmenupanel["CData"][Name]:SetMax( Max )
+ acfmenupanel["CData"][Name]:SetValue( Value )
+
+ if not acfmenupanel["CData"][Name.."_text"] and Desc then
+ acfmenupanel["CData"][Name.."_text"] = vgui.Create( "DLabel" )
+ acfmenupanel["CData"][Name.."_text"]:SetText( Desc or "" )
+ acfmenupanel["CData"][Name.."_text"]:SetDark( true )
+ acfmenupanel["CData"][Name.."_text"]:SetTall( 20 )
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name.."_text"] )
+ end
+ acfmenupanel["CData"][Name.."_text"]:SetText( Desc )
+ acfmenupanel["CData"][Name.."_text"]:SetSize( acfmenupanel.CustomDisplay:GetWide(), 10 )
+ acfmenupanel["CData"][Name.."_text"]:SizeToContentsX()
+
+end
+
+function PANEL:AmmoCheckbox(Name, Title, Desc) --Variable name in the table, slider text title, slider decimeals, description text below slider
+
+ if not acfmenupanel["CData"][Name] then
+ acfmenupanel["CData"][Name] = vgui.Create( "DCheckBoxLabel" )
+ acfmenupanel["CData"][Name]:SetText( Title or "" )
+ acfmenupanel["CData"][Name]:SetDark( true )
+ acfmenupanel["CData"][Name]:SizeToContents()
+ if acfmenupanel.AmmoData[Name] != nil then
+ acfmenupanel["CData"][Name]:SetChecked(acfmenupanel.AmmoData[Name])
+ else
+ acfmenupanel.AmmoData[Name] = false
+ end
+ acfmenupanel["CData"][Name].OnChange = function( check, bval )
+ acfmenupanel.AmmoData[Name] = bval
+ self:UpdateAttribs( {Name, bval} )
+ end
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name] )
+ end
+ acfmenupanel["CData"][Name]:SetText( Title )
+
+
+ if not acfmenupanel["CData"][Name.."_text"] and Desc then
+ acfmenupanel["CData"][Name.."_text"] = vgui.Create( "DLabel" )
+ acfmenupanel["CData"][Name.."_text"]:SetText( Desc or "" )
+ acfmenupanel["CData"][Name.."_text"]:SetDark( true )
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name.."_text"] )
+ end
+ acfmenupanel["CData"][Name.."_text"]:SetText( Desc )
+ acfmenupanel["CData"][Name.."_text"]:SetSize( acfmenupanel.CustomDisplay:GetWide(), 10 )
+ acfmenupanel["CData"][Name.."_text"]:SizeToContentsX()
+
+end
+
+function PANEL:CPanelText(Name, Desc)
+
+ if not acfmenupanel["CData"][Name.."_text"] then
+ acfmenupanel["CData"][Name.."_text"] = vgui.Create( "DLabel" )
+ acfmenupanel["CData"][Name.."_text"]:SetText( Desc or "" )
+ acfmenupanel["CData"][Name.."_text"]:SetDark( true )
+ acfmenupanel["CData"][Name.."_text"]:SetWrap(true)
+ acfmenupanel["CData"][Name.."_text"]:SetAutoStretchVertical( true )
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Name.."_text"] )
+ end
+ acfmenupanel["CData"][Name.."_text"]:SetText( Desc )
+ acfmenupanel["CData"][Name.."_text"]:SetSize( acfmenupanel.CustomDisplay:GetWide(), 10 )
+ acfmenupanel["CData"][Name.."_text"]:SizeToContentsY()
+
+end
diff --git a/lua/acf/client/cl_acfpermission.lua b/lua/acf/client/cl_acfpermission.lua
new file mode 100644
index 000000000..19ae72c01
--- /dev/null
+++ b/lua/acf/client/cl_acfpermission.lua
@@ -0,0 +1,116 @@
+-- Code modified from the NADMOD client permissions menu, by Nebual
+-- http://www.facepunch.com/showthread.php?t=1221183
+
+
+ACF = ACF or {}
+ACF.Permissions = ACF.Permissions or {}
+local this = ACF.Permissions
+
+local getPanelChecks = function() return {} end
+
+
+
+net.Receive("ACF_refreshfriends", function(len)
+ --Msg("\ncl refreshfriends\n")
+ local perms = net.ReadTable()
+ local checks = getPanelChecks()
+
+ --PrintTable(perms)
+
+ for k, check in pairs(checks) do
+ if perms[check.steamid] then
+ check:SetChecked(true)
+ else
+ check:SetChecked(false)
+ end
+ end
+
+end)
+
+
+
+net.Receive("ACF_refreshfeedback", function(len)
+ local success = net.ReadBit()
+ local str, notify
+
+ if success then
+ str = "Successfully updated your ACF damage permissions!"
+ notify = "NOTIFY_GENERIC"
+ else
+ str = "Failed to update your ACF damage permissions."
+ notify = "NOTIFY_ERROR"
+ end
+
+ GAMEMODE:AddNotify(str, notify, 7)
+
+end)
+
+
+
+function this.ApplyPermissions(checks)
+ perms = {}
+
+ for k, check in pairs(checks) do
+ if not check.steamid then Error("Encountered player checkbox without an attached SteamID!") end
+ perms[check.steamid] = check:GetChecked()
+ end
+
+ net.Start("ACF_dmgfriends")
+ net.WriteTable(perms)
+ net.SendToServer()
+end
+
+
+
+function this.ClientPanel(Panel)
+ Panel:ClearControls()
+ if !this.ClientCPanel then this.ClientCPanel = Panel end
+ Panel:SetName("ACF Damage Permissions")
+
+ local txt = Panel:Help("ACF Damage Permission Panel")
+ txt:SetContentAlignment( TEXT_ALIGN_CENTER )
+ txt:SetFont("DermaDefaultBold")
+ --txt:SetAutoStretchVertical(false)
+ --txt:SetHeight
+
+ local txt = Panel:Help("Allow or deny ACF damage to your props using this panel.\n\nThese preferences only work during the Build and Strict Build modes.")
+ txt:SetContentAlignment( TEXT_ALIGN_CENTER )
+ --txt:SetAutoStretchVertical(false)
+
+ Panel.playerChecks = {}
+ local checks = Panel.playerChecks
+
+ getPanelChecks = function() return checks end
+
+ local Players = player.GetAll()
+ for _, tar in pairs(Players) do
+ if(IsValid(tar)) then
+ local check = Panel:CheckBox(tar:Nick())
+ check.steamid = tar:SteamID()
+ --if tar == LocalPlayer() then check:SetChecked(true) end
+ checks[#checks+1] = check
+ end
+ end
+ local button = Panel:Button("Give Damage Permission")
+ button.DoClick = function() this.ApplyPermissions(Panel.playerChecks) end
+
+ net.Start("ACF_refreshfriends")
+ net.WriteBit(true)
+ net.SendToServer(ply)
+end
+
+
+
+function this.SpawnMenuOpen()
+ if this.ClientCPanel then
+ this.ClientPanel(this.ClientCPanel)
+ end
+end
+hook.Add("SpawnMenuOpen", "ACFPermissionsSpawnMenuOpen", this.SpawnMenuOpen)
+
+
+
+function this.PopulateToolMenu()
+ spawnmenu.AddToolMenuOption("Utilities", "ACF", "Damage Permission", "Damage Permission", "", "", this.ClientPanel)
+end
+hook.Add("PopulateToolMenu", "ACFPermissionsPopulateToolMenu", this.PopulateToolMenu)
diff --git a/lua/acf/client/cl_acfrender.lua b/lua/acf/client/cl_acfrender.lua
new file mode 100644
index 000000000..231180317
--- /dev/null
+++ b/lua/acf/client/cl_acfrender.lua
@@ -0,0 +1,74 @@
+local Damaged = {
+ CreateMaterial("ACF_Damaged1", "VertexLitGeneric", {["$basetexture"] = "damaged/damaged1"}),
+ CreateMaterial("ACF_Damaged2", "VertexLitGeneric", {["$basetexture"] = "damaged/damaged2"}),
+ CreateMaterial("ACF_Damaged3", "VertexLitGeneric", {["$basetexture"] = "damaged/damaged3"})
+}
+
+hook.Add("PostDrawOpaqueRenderables", "ACF_RenderDamage", function()
+ if not ACF_HealthRenderList then return end
+ cam.Start3D( EyePos(), EyeAngles() )
+ for k,ent in pairs( ACF_HealthRenderList ) do
+ --if ent:EntIndex() == 227 then print( ent.ACF_Material ) end
+ if IsValid(ent) then
+ render.ModelMaterialOverride( ent.ACF_Material )
+ render.SetBlend(math.Clamp(1- ent.ACF_HelathPercent,0,0.8))
+ ent:DrawModel()
+ elseif ACF_HealthRenderList then
+ table.remove(ACF_HealthRenderList,k)
+ end
+ end
+ render.ModelMaterialOverride()
+ render.SetBlend(1)
+ cam.End3D()
+end)
+
+net.Receive("ACF_RenderDamage", function()
+ local Table = net.ReadTable()
+ for k,v in ipairs( Table ) do
+ local ent, Health, MaxHealth = ents.GetByIndex( v.ID ), v.Health, v.MaxHealth
+ if not IsValid(ent) then return end
+ if Health != MaxHealth then
+ ent.ACF_Health = Health
+ ent.ACF_MaxHealth = MaxHealth
+ ent.ACF_HelathPercent = (Health/MaxHealth)
+ if ent.ACF_HelathPercent > 0.7 then
+ ent.ACF_Material = Damaged[1]
+ elseif ent.ACF_HelathPercent > 0.3 then
+ ent.ACF_Material = Damaged[2]
+ elseif ent.ACF_HelathPercent <= 0.3 then
+ ent.ACF_Material = Damaged[3]
+ end
+ ACF_HealthRenderList = ACF_HealthRenderList or {}
+ ACF_HealthRenderList[ent:EntIndex()] = ent
+ else
+ if ACF_HealthRenderList then
+ if #ACF_HealthRenderList<=1 then
+ ACF_HealthRenderList = nil
+ else
+ table.remove(ACF_HealthRenderList,ent:EntIndex())
+ end
+ if ent.ACF then
+ ent.ACF.Health = nil
+ ent.ACF.MaxHealth = nil
+ end
+ end
+ end
+ end
+end)
+
+--[[
+usermessage.Hook("Atest", function(msg)
+ local ent = ents.GetByIndex( msg:ReadFloat() )
+ local V1, V2, V3 = msg:ReadVector(), msg:ReadVector(), msg:ReadVector()
+ hook.Add("HUDPaint", "AtestHook", function()
+ if IsValid(ent) then
+ local Vec1, Vec2, Vec3 = ent:LocalToWorld(V1):ToScreen(), ent:LocalToWorld(V2):ToScreen(), ent:LocalToWorld(V3):ToScreen()
+ surface.DrawLine(Vec1.x,Vec1.y,Vec2.x,Vec2.y)
+ surface.DrawLine(Vec2.x,Vec2.y,Vec3.x,Vec3.y)
+ surface.DrawLine(Vec3.x,Vec3.y,Vec1.x,Vec1.y)
+ else
+ hook.Remove("AtestHook")
+ end
+ end)
+end)
+]]--
diff --git a/lua/acf/client/gui/cl_acfsetpermission.lua b/lua/acf/client/gui/cl_acfsetpermission.lua
new file mode 100644
index 000000000..ab6cb51cd
--- /dev/null
+++ b/lua/acf/client/gui/cl_acfsetpermission.lua
@@ -0,0 +1,211 @@
+
+
+local Menu = {}
+
+// the category the menu goes under
+Menu.Category = "ACF"
+
+
+// the name of the item
+Menu.Name = "Set Permission Mode"
+
+// the convar to execute when the player clicks on the tab
+Menu.Command = ""
+
+
+
+local Permissions = {}
+
+local PermissionModes = {}
+local CurrentPermission = "default"
+local DefaultPermission = "none"
+local ModeDescTxt
+local ModeDescDefault = "Can't find any info for this mode!"
+local currentMode
+local currentModeTxt = "\nThe current damage permission mode is %s."
+local introTxt = "Damage Permission Modes change the way that ACF damage works.\n\nYou can change the DP mode if you are an admin."
+local list
+
+
+
+net.Receive("ACF_refreshpermissions", function(len)
+
+ PermissionModes = net.ReadTable()
+ CurrentPermission = net.ReadString()
+ DefaultPermission = net.ReadString()
+
+ Permissions:Update()
+
+end)
+
+
+function Menu.MakePanel(Panel)
+
+ Permissions:RequestUpdate()
+
+ Panel:ClearControls()
+
+ if not PermissionModes then return end
+
+ Panel:SetName("Permission Modes")
+
+
+ local txt = Panel:Help(introTxt)
+ txt:SetContentAlignment( TEXT_ALIGN_CENTER )
+ --txt:SetAutoStretchVertical(false)
+ txt:SizeToContents()
+
+ Panel:AddItem(txt)
+
+ currentMode = Panel:Help(string.format(currentModeTxt, CurrentPermission))
+ currentMode:SetContentAlignment( TEXT_ALIGN_CENTER )
+ --currentMode:SetAutoStretchVertical(false)
+ currentMode:SetFont("DermaDefaultBold")
+ currentMode:SizeToContents()
+
+ Panel:AddItem(currentMode)
+
+
+ if LocalPlayer():IsAdmin() then
+
+ /*
+ local pmhelp = Panel:Help("Change Permission Mode")
+ pmhelp:SetContentAlignment( TEXT_ALIGN_CENTER )
+ pmhelp:SetAutoStretchVertical(false)
+ pmhelp:SetFont("DermaDefaultBold")
+ pmhelp:SizeToContents()
+ //*/
+
+ list = vgui.Create("DListView")
+ list:AddColumn("Mode")
+ list:AddColumn("Active")
+ list:AddColumn("Map Default")
+ list:SetMultiSelect(false)
+ list:SetSize(30,100)
+
+ for permission,desc in pairs(PermissionModes) do
+ list:AddLine(permission, "", "")
+ end
+
+ for id,line in pairs(list:GetLines()) do
+ if line:GetValue(1) == CurrentPermission then
+ list:GetLine(id):SetValue(2,"Yes")
+ end
+ if line:GetValue(1) == DefaultPermission then
+ list:GetLine(id):SetValue(3,"Yes")
+ end
+ end
+
+ list.OnRowSelected = function(panel, line)
+ if ModeDescTxt then
+ ModeDescTxt:SetText(PermissionModes[panel:GetLine(line):GetValue(1)] or ModeDescDefault)
+ ModeDescTxt:SizeToContents()
+ end
+ end
+
+ Panel:AddItem(list)
+
+
+ local txt = Panel:Help("What this mode does:")
+ txt:SetContentAlignment( TEXT_ALIGN_CENTER )
+ --txt:SetAutoStretchVertical(false)
+ txt:SetFont("DermaDefaultBold")
+ txt:SizeToContents()
+ --txt:SetHeight(20)
+
+ Panel:AddItem(txt)
+
+
+ ModeDescTxt = Panel:Help(PermissionModes[CurrentPermission] or ModeDescDefault)
+ ModeDescTxt:SetContentAlignment( TEXT_ALIGN_CENTER )
+ --txt:SetAutoStretchVertical(false)
+ ModeDescTxt:SizeToContents()
+
+ Panel:AddItem(ModeDescTxt)
+
+
+ local button = Panel:Button("Set Permission Mode")
+ button.DoClick = function()
+ local line = list:GetLine(list:GetSelectedLine())
+ if not line then
+ Permissions:RequestUpdate()
+ return
+ end
+
+ local mode = line and line:GetValue(1)
+ RunConsoleCommand("ACF_setpermissionmode",mode)
+ end
+
+ Panel:AddItem(button)
+
+
+ local button2 = Panel:Button("Set Default Permission Mode")
+ button2.DoClick = function()
+ local line = list:GetLine(list:GetSelectedLine())
+ if not line then
+ Permissions:RequestUpdate()
+ return
+ end
+
+ local mode = line and line:GetValue(1)
+ RunConsoleCommand("ACF_setdefaultpermissionmode",mode)
+ end
+
+ Panel:AddItem(button2)
+
+ end
+end
+
+
+function Permissions:Update()
+
+ if list then
+ for id,line in pairs(list:GetLines()) do
+ if line:GetValue(1) == CurrentPermission then
+ list:GetLine(id):SetValue(2,"Yes")
+ else
+ list:GetLine(id):SetValue(2,"")
+ end
+ if line:GetValue(1) == DefaultPermission then
+ list:GetLine(id):SetValue(3,"Yes")
+ else
+ list:GetLine(id):SetValue(3,"")
+ end
+ end
+ end
+
+ if currentMode then
+ currentMode:SetText(string.format(currentModeTxt, CurrentPermission))
+ currentMode:SizeToContents()
+ end
+
+end
+
+
+function Permissions:RequestUpdate()
+ net.Start("ACF_refreshpermissions")
+ net.WriteBit(true)
+ net.SendToServer()
+end
+
+
+function Menu.OnSpawnmenuOpen()
+ Permissions:RequestUpdate()
+end
+
+
+
+local cat = Menu.Category
+local item = Menu.Name
+local var = Menu.Command
+local open = Menu.OnSpawnmenuOpen
+local panel = Menu.MakePanel
+local hookname = string.Replace(item," ","_")
+
+
+hook.Add("SpawnMenuOpen", "ACF.SpawnMenuOpen."..hookname, open)
+
+
+hook.Add("PopulateToolMenu", "ACF.PopulateToolMenu."..hookname, function()
+ spawnmenu.AddToolMenuOption("Utilities", cat, item, item, var, "", panel)
+end)
diff --git a/lua/acf/server/permissionmodes/acf_pmode_battle.lua b/lua/acf/server/permissionmodes/acf_pmode_battle.lua
new file mode 100644
index 000000000..0eb729848
--- /dev/null
+++ b/lua/acf/server/permissionmodes/acf_pmode_battle.lua
@@ -0,0 +1,97 @@
+/**
+ ACF Permission mode: Battle
+ This mode enables safezones and battlefield.
+ All things within safezones are protected from all registered ACF damage.
+ All things in the battlefield are vulnerable to all ACF damage.
+//*/
+if not ACF or not ACF.Permissions or not ACF.Permissions.RegisterMode then error("ACF: Tried to load the " .. modename .. " permission-mode before the permission-core has loaded!") return end
+local perms = ACF.Permissions
+
+
+// the name for this mode used in commands and identification
+local modename = "battle"
+
+// a short description of what the mode does
+local modedescription = "Enables safe-zones and battlefield. No ACF damage can occur in a safe-zone."
+
+
+// battle-mode specifics: how much hp/armour should the players have?
+local MAX_HP = 100
+local MAX_Armour = 50
+local ShouldDisableNoclip = false
+
+// if the attacker or victim can't be identified, what should we do? true allows damage, false blocks it.
+local DefaultPermission = false
+
+
+
+/*
+ Defines the behaviour of ACF damage protection under this protection mode.
+ This function is called every time an entity can be affected by potential ACF damage.
+ Args;
+ owner Player: The owner of the potentially-damaged entity
+ attacker Player: The initiator of the ACF damage event
+ ent Entity: The entity which may be damaged.
+ Return: boolean
+ true if the entity should be damaged, false if the entity should be protected from the damage.
+//*/
+local function modepermission(owner, attacker, ent)
+ local szs = perms.Safezones
+
+ if szs then
+ local entpos = ent:GetPos()
+ local attpos = attacker:GetPos()
+
+ if perms.IsInSafezone(entpos) or perms.IsInSafezone(attpos) then return false end
+ end
+
+ return
+end
+
+
+
+function tellPlyAboutZones(ply, zone, oldzone)
+ if perms.DamagePermission ~= modepermission then return end
+ ply:SendLua("chat.AddText(Color(" .. (zone and "0,255,0" or "255,0,0") .. "),\"You have entered the " .. (zone and zone .. " safezone." or "battlefield!") .. "\")")
+end
+hook.Add("ACF_PlayerChangedZone", "ACF_TellPlyAboutSafezoneBattle", tellPlyAboutZones)
+
+
+
+local function DisableNoclipPressInBattle( ply, wantsNoclipOn )
+ if not (ShouldDisableNoclip and wantsNoclipOn and table.KeyFromValue(perms.Modes, perms.DamagePermission) == modename) then return end
+
+ return (perms.IsInSafezone(ply:GetPos()) ~= false)
+end
+hook.Add( "PlayerNoClip", "ACF_DisableNoclipPressInBattle", DisableNoclipPressInBattle )
+
+
+
+local function modethink()
+ for k, ply in pairs(player.GetAll()) do
+ --print(ply:GetPos(), perms.IsInSafezone(ply:GetPos()))
+ if not perms.IsInSafezone(ply:GetPos()) then
+ ply:GodDisable()
+
+ if ShouldDisableNoclip and ply:GetMoveType() ~= MOVETYPE_WALK then
+ ply:SetMoveType(MOVETYPE_WALK)
+ end
+
+ local HP = ply:Health()
+ local AR = ply:Armor()
+
+ if HP > MAX_HP then
+ ply:SetHealth(MAX_HP)
+ end
+
+ if AR > MAX_Armour then
+ ply:SetArmor(MAX_Armour)
+ end
+ end
+ end
+
+ return 0.25
+end
+
+
+perms.RegisterMode(modepermission, modename, modedescription, false, modethink)
\ No newline at end of file
diff --git a/lua/acf/server/permissionmodes/acf_pmode_build.lua b/lua/acf/server/permissionmodes/acf_pmode_build.lua
new file mode 100644
index 000000000..813627569
--- /dev/null
+++ b/lua/acf/server/permissionmodes/acf_pmode_build.lua
@@ -0,0 +1,65 @@
+/**
+ ACF Permission mode: Build
+ This mode blocks all damage to entities without the owner's permission.
+ Owners can permit damage from specific players.
+ Players and NPCs remain vulnerable to damage. This is what admin mods are for.
+ This mode requires a CPPI-compatible prop-protector to function properly.
+//*/
+
+if not ACF or not ACF.Permissions or not ACF.Permissions.RegisterMode then error("ACF: Tried to load the " .. modename .. " permission-mode before the permission-core has loaded!") end
+local perms = ACF.Permissions
+
+
+// the name for this mode used in commands and identification
+local modename = "build"
+
+// a short description of what the mode does
+local modedescription = "Disables all ACF damage unless the owner permits it. PvP is allowed."
+
+// if the attacker or victim can't be identified, what should we do? true allows damage, false blocks it.
+local DefaultPermission = false
+
+
+/*
+ Defines the behaviour of ACF damage protection under this protection mode.
+ This function is called every time an entity can be affected by potential ACF damage.
+ Args;
+ owner Player: The owner of the potentially-damaged entity
+ attacker Player: The initiator of the ACF damage event
+ ent Entity: The entity which may be damaged.
+ Return: boolean
+ true if the entity should be damaged, false if the entity should be protected from the damage.
+//*/
+local function modepermission(owner, attacker, ent)
+
+ if IsValid(ent) and ent:IsPlayer() or ent:IsNPC() then
+ --print("is squishy")
+ return true
+ end
+
+ if not (owner.SteamID or attacker.SteamID) then
+ --print("ACF ERROR: owner or attacker is not a player!", tostring(owner), tostring(attacker), "\n", debug.traceback())
+ if DefaultPermission then return
+ else return DefaultPermission end
+ end
+
+ local ownerid = owner:SteamID()
+ local attackerid = attacker:SteamID()
+ local ownerperms = perms.GetDamagePermissions(ownerid)
+
+ if ownerperms[attackerid] then
+ --print("permitted")
+ return
+ end
+
+ --print("disallowed")
+ return false
+end
+
+
+if not CPPI then
+ print("WARNING: ACF protection mode \"" .. modename .. "\" works best with a CPPI-compliant prop protection script. Try NADMOD!")
+end
+
+
+perms.RegisterMode(modepermission, modename, modedescription, false, nil, DefaultPermission)
diff --git a/lua/acf/server/permissionmodes/acf_pmode_none.lua b/lua/acf/server/permissionmodes/acf_pmode_none.lua
new file mode 100644
index 000000000..97ce928aa
--- /dev/null
+++ b/lua/acf/server/permissionmodes/acf_pmode_none.lua
@@ -0,0 +1,32 @@
+/**
+ ACF Permission mode: None
+ This mode completely disables damage protection.
+//*/
+
+if not ACF or not ACF.Permissions or not ACF.Permissions.RegisterMode then error("ACF: Tried to load the " .. modename .. " permission-mode before the permission-core has loaded!") end
+local perms = ACF.Permissions
+
+// the name for this mode used in commands and identification
+local modename = "none"
+
+// a short description of what the mode does
+local modedescription = "Completely disables damage protection."
+
+
+/*
+ Defines the behaviour of ACF damage protection under this protection mode.
+ This function is called every time an entity can be affected by potential ACF damage.
+ Args;
+ owner Player: The owner of the potentially-damaged entity
+ attacker Player: The initiator of the ACF damage event
+ ent Entity: The entity which may be damaged.
+ Return: boolean
+ true if the entity should be damaged, false if the entity should be protected from the damage.
+//*/
+local function modepermission(owner, attacker, ent)
+ return
+end
+
+
+
+perms.RegisterMode(modepermission, modename, modedescription, true, nil, true)
\ No newline at end of file
diff --git a/lua/acf/server/permissionmodes/acf_pmode_safe.lua b/lua/acf/server/permissionmodes/acf_pmode_safe.lua
new file mode 100644
index 000000000..8cdb3192f
--- /dev/null
+++ b/lua/acf/server/permissionmodes/acf_pmode_safe.lua
@@ -0,0 +1,32 @@
+/**
+ ACF Permission mode: Safe
+ This mode completely disables damage upon everything.
+//*/
+
+if not ACF or not ACF.Permissions or not ACF.Permissions.RegisterMode then error("ACF: Tried to load the " .. modename .. " permission-mode before the permission-core has loaded!") end
+local perms = ACF.Permissions
+
+
+// the name for this mode used in commands and identification
+local modename = "safe"
+
+// a short description of what the mode does
+local modedescription = "Completely disables damage upon everything."
+
+
+/*
+ Defines the behaviour of ACF damage protection under this protection mode.
+ This function is called every time an entity can be affected by potential ACF damage.
+ Args;
+ owner Player: The owner of the potentially-damaged entity
+ attacker Player: The initiator of the ACF damage event
+ ent Entity: The entity which may be damaged.
+ Return: boolean
+ true if the entity should be damaged, false if the entity should be protected from the damage.
+//*/
+local function modepermission(owner, attacker, ent)
+ return false
+end
+
+
+perms.RegisterMode(modepermission, modename, modedescription, false, nil, false)
\ No newline at end of file
diff --git a/lua/acf/server/permissionmodes/acf_pmode_strictbuild.lua b/lua/acf/server/permissionmodes/acf_pmode_strictbuild.lua
new file mode 100644
index 000000000..f83d86751
--- /dev/null
+++ b/lua/acf/server/permissionmodes/acf_pmode_strictbuild.lua
@@ -0,0 +1,60 @@
+/**
+ ACF Permission mode: Strict Build
+ This mode blocks all damage to entities without the owner's permission.
+ Owners can permit damage from specific players.
+ Players and NPCs are also protected in this mode.
+ This mode requires a CPPI-compatible prop-protector to function properly.
+//*/
+
+if not ACF or not ACF.Permissions or not ACF.Permissions.RegisterMode then error("ACF: Tried to load the " .. modename .. " permission-mode before the permission-core has loaded!") end
+local perms = ACF.Permissions
+
+
+// the name for this mode used in commands and identification
+local modename = "strictbuild"
+
+// a short description of what the mode does
+local modedescription = "Disables all ACF damage unless the owner permits it. PvP is disallowed."
+
+// if the attacker or victim can't be identified, what should we do? true allows damage, false blocks it.
+local DefaultPermission = false
+
+
+/*
+ Defines the behaviour of ACF damage protection under this protection mode.
+ This function is called every time an entity can be affected by potential ACF damage.
+ Args;
+ owner Player: The owner of the potentially-damaged entity
+ attacker Player: The initiator of the ACF damage event
+ ent Entity: The entity which may be damaged.
+ Return: boolean
+ true if the entity should be damaged, false if the entity should be protected from the damage.
+//*/
+local function modepermission(owner, attacker, ent)
+
+ if not (owner.SteamID or attacker.SteamID) then
+ --print("ACF ERROR: owner or attacker is not a player!", tostring(owner), tostring(attacker), "\n", debug.traceback())
+ if DefaultPermission then return
+ else return DefaultPermission end
+ end
+
+ local ownerid = owner:SteamID()
+ local attackerid = attacker:SteamID()
+ local ownerperms = perms.GetDamagePermissions(ownerid)
+
+ if ownerperms[attackerid] then
+ --print("permitted")
+ return
+ end
+
+ --print("disallowed")
+ return false
+end
+
+
+if not CPPI then
+ print("WARNING: ACF protection mode \"" .. modename .. "\" works best with a CPPI-compliant prop protection script. Try NADMOD!")
+end
+
+
+perms.RegisterMode(modepermission, modename, modedescription, false, nil, DefaultPermission)
diff --git a/lua/acf/server/sv_acfballistics.lua b/lua/acf/server/sv_acfballistics.lua
new file mode 100644
index 000000000..8bb91ff56
--- /dev/null
+++ b/lua/acf/server/sv_acfballistics.lua
@@ -0,0 +1,306 @@
+-- init
+ACF.Bullet = {} --when ACF is loaded, this table holds bullets
+ACF.CurBulletIndex = 0 --used to track where to insert bullets
+ACF.BulletIndexLimt = 1000 --The maximum number of bullets in flight at any one time. oldest existing bullets are overwritten if limit overflow
+
+ACF.TraceFilter = { --entities that cause issue with acf and should be not be processed at all
+ prop_vehicle_crane = true,
+ prop_dynamic = true
+ }
+ACF.SkyboxGraceZone = 100 --grace zone for the high angle fire
+
+-- optimization; reuse tables for ballistics traces
+local FlightRes = { }
+local FlightTr = { output = FlightRes }
+-- end init
+
+--creates a new bullet being fired
+function ACF_CreateBullet( BulletData )
+
+ ACF.CurBulletIndex = ACF.CurBulletIndex + 1 --Increment the index
+ if ACF.CurBulletIndex > ACF.BulletIndexLimt then
+ ACF.CurBulletIndex = 1
+ end
+
+ --Those are BulletData settings that are global and shouldn't change round to round
+ local cvarGrav = GetConVar("sv_gravity")
+ BulletData["Accel"] = Vector(0,0,cvarGrav:GetInt()*-1)
+ BulletData["LastThink"] = ACF.SysTime
+ BulletData["FlightTime"] = 0
+ BulletData["TraceBackComp"] = 0
+ --BulletData.FiredTime = ACF.SysTime --same as fuse inittime, can combine when readding
+ --BulletData.FiredPos = BulletData.Pos --when adding back in, update acfdamage roundimpact rico
+ if type(BulletData["FuseLength"]) ~= "number" then
+ BulletData["FuseLength"] = 0
+ else
+ --print("Has fuse")
+ if BulletData["FuseLength"] > 0 then
+ BulletData["InitTime"] = ACF.SysTime
+ end
+ end
+
+ --Check the Gun's velocity and add a modifier to the flighttime so the traceback system doesn't hit the originating contraption if it's moving along the shell path
+ if BulletData["Gun"]:IsValid() then
+ BulletData["TraceBackComp"] = math.max(ACF_GetPhysicalParent(BulletData["Gun"]):GetPhysicsObject():GetVelocity():Dot(BulletData["Flight"]:GetNormalized()),0)
+ --print(BulletData["TraceBackComp"])
+ if BulletData["Gun"].sitp_inspace then
+ BulletData["Accel"] = Vector(0, 0, 0)
+ BulletData["DragCoef"] = 0
+ end
+ end
+ BulletData["Filter"] = { BulletData["Gun"] }
+ BulletData["Index"] = ACF.CurBulletIndex
+ ACF.Bullet[ACF.CurBulletIndex] = table.Copy(BulletData) --Place the bullet at the current index pos
+ ACF_BulletClient( ACF.CurBulletIndex, ACF.Bullet[ACF.CurBulletIndex], "Init" , 0 )
+ ACF_CalcBulletFlight( ACF.CurBulletIndex, ACF.Bullet[ACF.CurBulletIndex] )
+
+end
+
+--global update function where acf updates ALL bullets at once--this runs once per tick, handling bullet physics for all bullets in table.
+function ACF_ManageBullets()
+ for Index,Bullet in pairs(ACF.Bullet) do
+ if not Bullet.HandlesOwnIteration then
+ ACF_CalcBulletFlight( Index, Bullet ) --This is the bullet entry in the table, the Index var omnipresent refers to this
+ end
+ end
+end
+
+hook.Add("Tick", "ACF_ManageBullets", ACF_ManageBullets)
+
+--removes the bullet from acf
+function ACF_RemoveBullet( Index )
+ local Bullet = ACF.Bullet[Index]
+ ACF.Bullet[Index] = nil
+ if Bullet and Bullet.OnRemoved then Bullet:OnRemoved() end
+end
+
+--checks the visclips of an entity, to determine if round should pass through or not
+-- ignores anything that's not a prop (acf components, seats) or with nil volume (makesphere props)
+function ACF_CheckClips( Ent, HitPos )
+ if not IsValid(Ent) or (Ent.ClipData == nil)
+ or (not (Ent:GetClass() == "prop_physics"))
+ or (Ent:GetPhysicsObject():GetVolume() == nil) -- makesphere
+ then return false end
+
+ local normal
+ local origin
+ for i=1, #Ent.ClipData do
+ normal = Ent:LocalToWorldAngles(Ent.ClipData[i]["n"]):Forward()
+ origin = Ent:LocalToWorld(Ent:OBBCenter())+normal*Ent.ClipData[i]["d"]
+ --debugoverlay.BoxAngles( origin, Vector(0,-24,-24), Vector(1,24,24), Ent:LocalToWorldAngles(Ent.ClipData[i]["n"]), 15, Color(255,0,0,32) )
+ if normal:Dot((origin - HitPos):GetNormalized()) > 0 then return true end
+ end
+
+ return false
+end
+
+--handles non-terminal ballistics and fusing of bullets
+function ACF_CalcBulletFlight( Index, Bullet, BackTraceOverride )
+ -- perf concern: use direct function call stored on bullet over hook system.
+ if Bullet.PreCalcFlight then Bullet:PreCalcFlight() end
+
+ if not Bullet.LastThink then ACF_RemoveBullet( Index ) end
+
+ if BackTraceOverride then Bullet.FlightTime = 0 end
+ local DeltaTime = ACF.SysTime - Bullet.LastThink
+
+ --actual motion of the bullet
+ local Drag = Bullet.Flight:GetNormalized() * (Bullet.DragCoef * Bullet.Flight:LengthSqr()) / ACF.DragDiv
+ Bullet.NextPos = Bullet.Pos + (Bullet.Flight * ACF.VelScale * DeltaTime) --Calculates the next shell position
+ Bullet.Flight = Bullet.Flight + (Bullet.Accel - Drag)*DeltaTime --Calculates the next shell vector
+ Bullet.StartTrace = Bullet.Pos - Bullet.Flight:GetNormalized()*(math.min(ACF.PhysMaxVel*0.025,(Bullet.FlightTime*Bullet.Flight:Length()-Bullet.TraceBackComp*DeltaTime)))
+
+ --print(math.Round((Bullet.Pos-Bullet.StartTrace):Length(),1))
+ --debugoverlay.Cross(Bullet.Pos,3,15,Color(255,255,255,32), true) --true start
+ --debugoverlay.Box(Bullet.StartTrace,Vector(-2,-2,-2),Vector(2,2,2),15,Color(0,255,0,32), true) --backtrace start
+ --debugoverlay.EntityTextAtPosition(Bullet.StartTrace, 0, "Tr", 15)
+ --debugoverlay.EntityTextAtPosition(Bullet.Pos, 0, "Pos", 15)
+ --debugoverlay.Line( Bullet.Pos+Vector(0,0,1), Bullet.StartTrace+Vector(0,0,1), 15, Color(0, 255, 255), true )
+ --debugoverlay.Line( Bullet.NextPos+VectorRand(), Bullet.StartTrace+VectorRand(), 15, ColorRand(), true )
+
+ --updating timestep timers
+ Bullet.LastThink = ACF.SysTime
+ Bullet.FlightTime = Bullet.FlightTime + DeltaTime
+
+ ACF_DoBulletsFlight( Index, Bullet )
+
+ -- perf concern: use direct function call stored on bullet over hook system.
+ if Bullet.PostCalcFlight then Bullet:PostCalcFlight() end
+end
+
+--handles bullet terminal ballistics, fusing, and visclip checking
+function ACF_DoBulletsFlight( Index, Bullet )
+ local CanDo = hook.Run("ACF_BulletsFlight", Index, Bullet )
+ if CanDo == false then return end
+ if Bullet.FuseLength and Bullet.FuseLength > 0 then
+ local Time = ACF.SysTime - Bullet.InitTime
+ if Time > Bullet.FuseLength then
+ --print("Explode")
+ if not util.IsInWorld(Bullet.Pos) then
+ ACF_RemoveBullet( Index )
+ else
+ if Bullet.OnEndFlight then Bullet.OnEndFlight(Index, Bullet, nil) end -- nil was flightres, garbage data this early in code
+ ACF_BulletClient( Index, Bullet, "Update" , 1 , Bullet.Pos ) -- defined at bottom
+ ACF_BulletEndFlight = ACF.RoundTypes[Bullet.Type]["endflight"]
+ ACF_BulletEndFlight( Index, Bullet, Bullet.Pos, Bullet.Flight:GetNormalized() )
+ end
+ end
+ end
+
+ --if we're out of skybox, keep calculating position. If we have too long out of skybox, remove bullet
+ if Bullet.SkyLvL then
+ --We don't want to calculate bullets that will never come back to map
+ if (ACF.CurTime - Bullet.LifeTime) > 30 then
+ ACF_RemoveBullet( Index )
+ return
+ end
+ --We don't want rounds to hit the skybox top, but to pass through and come back down
+ if Bullet.NextPos.z + ACF.SkyboxGraceZone > Bullet.SkyLvL then --add in a bit of grace zone
+ Bullet.Pos = Bullet.NextPos
+ return
+ --We do want rounds outside of the world but not skybox top to be deleted
+ elseif not util.IsInWorld(Bullet.NextPos) then
+ ACF_RemoveBullet( Index )
+ return
+ --We fall back to this default
+ else
+ Bullet.SkyLvL = nil
+ Bullet.LifeTime = nil
+ Bullet.Pos = Bullet.NextPos
+ Bullet.SkipNextHit = true
+ return
+ end
+ end
+
+ -- I'm leaving disabled tracehull setup here, from when I was testing it. just need to set the mins/maxs and swap trace methods a few lines below. --ferv
+ -- tracehull is causing issues with hit detections on clips (ie slipping through clipped glacis seams; reported hitpos is on clipped side of both?)
+ -- ocassional issues with determining hit normal on prop seams, may be related to clip seams
+ -- issues with determining if a glancing hit; these settings have a reduced hull size so that only non-glancing hits count
+ -- possible fix: do a secondary traceline of flight through tracehull hitpos, as if the bullet was travelling through hitpos
+ -- worth the extra trace overhead? only run hulls for large shells? 3" (75mm)? 4" (100mm)? extra complexity for handling different cal traces
+
+ --local radius = 0.3937 * Bullet.Caliber / 2 -- caliber (shell diameter) is in cm.
+ --FlightTr.maxs = Vector(radius, radius, radius) * 0.667 -- defining hullsize; reduced size to filter out glancing hits that would deal full damage
+ --FlightTr.mins = -FlightTr.maxs
+ FlightTr.mask = Bullet.Caliber <= 0.3 and MASK_SHOT or MASK_SOLID -- cals 30mm and smaller will pass through things like chain link fences
+ FlightTr.filter = Bullet.Filter -- any changes to bullet filter will be reflected in the trace
+
+ --perform the trace for damage
+ local RetryTrace = true
+ while RetryTrace do --if trace hits clipped part of prop, add prop to trace filter and retry
+ RetryTrace = false
+ FlightTr.start = Bullet.StartTrace
+ FlightTr.endpos = Bullet.NextPos + Bullet.Flight:GetNormalized()*(ACF.PhysMaxVel * 0.025) --compensation
+ util.TraceLine(FlightTr) -- trace result is stored in supplied output FlightRes (at top of file)
+ --util.TraceHull(FlightTr)
+
+ --We hit something that's not world, if it's visclipped, filter it out and retry
+ if FlightRes.HitNonWorld and ACF_CheckClips( FlightRes.Entity, FlightRes.HitPos ) then
+ table.insert( Bullet.Filter , FlightRes.Entity )
+ RetryTrace = true
+ end
+ end
+
+ --bullet is told to ignore the next hit, so it does and resets flag
+ if Bullet.SkipNextHit then
+ if not FlightRes.StartSolid and not FlightRes.HitNoDraw then Bullet.SkipNextHit = nil end
+ Bullet.Pos = Bullet.NextPos
+
+ --bullet hit something that isn't world and is allowed to hit
+ elseif FlightRes.HitNonWorld and not ACF.TraceFilter[FlightRes.Entity:GetClass()] then --don't process ACF.TraceFilter ents
+ --If we hit stuff then send the resolution to the bullets damage function
+ ACF_BulletPropImpact = ACF.RoundTypes[Bullet.Type]["propimpact"]
+ local Retry = ACF_BulletPropImpact( Index, Bullet, FlightRes.Entity , FlightRes.HitNormal , FlightRes.HitPos , FlightRes.HitGroup )
+ if Retry == "Penetrated" then --If we should do the same trace again, then do so
+ if Bullet.OnPenetrated then Bullet.OnPenetrated(Index, Bullet, FlightRes) end
+ ACF_BulletClient( Index, Bullet, "Update" , 2 , FlightRes.HitPos )
+ ACF_DoBulletsFlight( Index, Bullet )
+ elseif Retry == "Ricochet" then
+ if Bullet.OnRicocheted then Bullet.OnRicocheted(Index, Bullet, FlightRes) end
+ ACF_BulletClient( Index, Bullet, "Update" , 3 , FlightRes.HitPos )
+ ACF_CalcBulletFlight( Index, Bullet, true )
+ else --Else end the flight here
+ if Bullet.OnEndFlight then Bullet.OnEndFlight(Index, Bullet, FlightRes) end
+ ACF_BulletClient( Index, Bullet, "Update" , 1 , FlightRes.HitPos )
+ ACF_BulletEndFlight = ACF.RoundTypes[Bullet.Type]["endflight"]
+ ACF_BulletEndFlight( Index, Bullet, FlightRes.HitPos, FlightRes.HitNormal )
+ end
+
+ --bullet hit the world
+ elseif FlightRes.HitWorld then
+ if not FlightRes.HitSky then --If we hit the world then try to see if it's thin enough to penetrate
+ ACF_BulletWorldImpact = ACF.RoundTypes[Bullet.Type]["worldimpact"]
+ local Retry = ACF_BulletWorldImpact( Index, Bullet, FlightRes.HitPos, FlightRes.HitNormal )
+ if Retry == "Penetrated" then --if it is, we soldier on
+ if Bullet.OnPenetrated then Bullet.OnPenetrated(Index, Bullet, FlightRes) end
+ ACF_BulletClient( Index, Bullet, "Update" , 2 , FlightRes.HitPos )
+ ACF_CalcBulletFlight( Index, Bullet, true ) --The world ain't going to move, so we say True for the backtrace override
+ elseif Retry == "Ricochet" then
+ if Bullet.OnRicocheted then Bullet.OnRicocheted(Index, Bullet, FlightRes) end
+ ACF_BulletClient( Index, Bullet, "Update" , 3 , FlightRes.HitPos )
+ ACF_CalcBulletFlight( Index, Bullet, true )
+ else --If not, end of the line, boyo
+ if Bullet.OnEndFlight then Bullet.OnEndFlight(Index, Bullet, FlightRes) end
+ ACF_BulletClient( Index, Bullet, "Update" , 1 , FlightRes.HitPos )
+ ACF_BulletEndFlight = ACF.RoundTypes[Bullet.Type]["endflight"]
+ ACF_BulletEndFlight( Index, Bullet, FlightRes.HitPos, FlightRes.HitNormal )
+ end
+
+ else --hit skybox
+ if FlightRes.HitNormal == Vector(0,0,-1) then --only if leaving top of skybox
+ Bullet.SkyLvL = FlightRes.HitPos.z -- store the Z value where bullet left skybox, used to check world re-entry
+ Bullet.LifeTime = ACF.CurTime
+ Bullet.Pos = Bullet.NextPos
+ else
+ ACF_RemoveBullet( Index )
+ end
+ end
+
+ --bullet hit nothing, keep flying
+ else
+ Bullet.Pos = Bullet.NextPos
+ end
+
+end
+
+function ACF_BulletClient( Index, Bullet, Type, Hit, HitPos )
+
+ if Type == "Update" then
+ local Effect = EffectData()
+ Effect:SetAttachment( Index ) --Bulet Index
+ Effect:SetStart( Bullet.Flight/10 ) --Bullet Direction
+ if Hit > 0 then -- If there is a hit then set the effect pos to the impact pos instead of the retry pos
+ Effect:SetOrigin( HitPos ) --Bullet Pos
+ else
+ Effect:SetOrigin( Bullet.Pos )
+ end
+ Effect:SetScale( Hit ) --Hit Type
+ util.Effect( "ACF_BulletEffect", Effect, true, true )
+
+ else
+ local Effect = EffectData()
+ local Filler = 0
+ if Bullet["FillerMass"] then Filler = Bullet["FillerMass"]*15 end
+ Effect:SetAttachment( Index ) --Bulet Index
+ Effect:SetStart( Bullet.Flight/10 ) --Bullet Direction
+ Effect:SetOrigin( Bullet.Pos )
+ Effect:SetEntity( Entity(Bullet["Crate"]) )
+ Effect:SetScale( 0 )
+ util.Effect( "ACF_BulletEffect", Effect, true, true )
+
+ end
+
+end
+
+function ACF_BulletWorldImpact( Bullet, Index, HitPos, HitNormal )
+ --You overwrite this with your own function, defined in the ammo definition file
+end
+
+function ACF_BulletPropImpact( Bullet, Index, Target, HitNormal, HitPos )
+ --You overwrite this with your own function, defined in the ammo definition file
+end
+
+function ACF_BulletEndFlight( Bullet, Index, HitPos )
+ --You overwrite this with your own function, defined in the ammo definition file
+end
+
diff --git a/lua/acf/server/sv_acfbase.lua b/lua/acf/server/sv_acfbase.lua
new file mode 100644
index 000000000..9a77603bc
--- /dev/null
+++ b/lua/acf/server/sv_acfbase.lua
@@ -0,0 +1,403 @@
+local UpdateIndex = 0
+function ACF_UpdateVisualHealth(Entity)
+ if Entity.ACF.PrHealth == Entity.ACF.Health then return end
+ if not ACF_HealthUpdateList then
+ ACF_HealthUpdateList = {}
+ timer.Create("ACF_HealthUpdateList", 1, 1, function() // We should send things slowly to not overload traffic.
+ local Table = {}
+ for k,v in pairs(ACF_HealthUpdateList) do
+ if IsValid( v ) then
+ table.insert(Table,{ID = v:EntIndex(), Health = v.ACF.Health, MaxHealth = v.ACF.MaxHealth})
+ end
+ end
+ net.Start("ACF_RenderDamage")
+ net.WriteTable(Table)
+ net.Broadcast()
+ ACF_HealthUpdateList = nil
+ end)
+ end
+ table.insert(ACF_HealthUpdateList, Entity)
+end
+
+function ACF_Activate ( Entity , Recalc )
+
+ --Density of steel = 7.8g cm3 so 7.8kg for a 1mx1m plate 1m thick
+ if Entity.SpecialHealth then
+ Entity:ACF_Activate( Recalc )
+ return
+ end
+ Entity.ACF = Entity.ACF or {}
+
+ local Count
+ local PhysObj = Entity:GetPhysicsObject()
+ if PhysObj:GetMesh() then Count = #PhysObj:GetMesh() end
+ if PhysObj:IsValid() and Count and Count>100 then
+
+ if not Entity.ACF.Aera then
+ Entity.ACF.Aera = (PhysObj:GetSurfaceArea() * 6.45) * 0.52505066107
+ end
+ --if not Entity.ACF.Volume then
+ -- Entity.ACF.Volume = (PhysObj:GetVolume() * 16.38)
+ --end
+ else
+ local Size = Entity.OBBMaxs(Entity) - Entity.OBBMins(Entity)
+ if not Entity.ACF.Aera then
+ Entity.ACF.Aera = ((Size.x * Size.y)+(Size.x * Size.z)+(Size.y * Size.z)) * 6.45 --^ 1.15
+ end
+ --if not Entity.ACF.Volume then
+ -- Entity.ACF.Volume = Size.x * Size.y * Size.z * 16.38
+ --end
+ end
+
+ Entity.ACF.Ductility = Entity.ACF.Ductility or 0
+ --local Area = (Entity.ACF.Aera+Entity.ACF.Aera*math.Clamp(Entity.ACF.Ductility,-0.8,0.8))
+ local Area = Entity.ACF.Aera
+ local Ductility = math.Clamp( Entity.ACF.Ductility, -0.8, 0.8 )
+ local Armour = ACF_CalcArmor( Area, Ductility, Entity:GetPhysicsObject():GetMass() ) -- So we get the equivalent thickness of that prop in mm if all its weight was a steel plate
+ local Health = ( Area / ACF.Threshold ) * ( 1 + Ductility ) -- Setting the threshold of the prop aera gone
+
+ local Percent = 1
+
+ if Recalc and Entity.ACF.Health and Entity.ACF.MaxHealth then
+ Percent = Entity.ACF.Health/Entity.ACF.MaxHealth
+ end
+
+ Entity.ACF.Health = Health * Percent
+ Entity.ACF.MaxHealth = Health
+ Entity.ACF.Armour = (Armour) * (0.5 + Percent/2)
+ Entity.ACF.MaxArmour = (Armour) * ACF.ArmorMod
+ Entity.ACF.Type = nil
+ Entity.ACF.Mass = PhysObj:GetMass()
+ --Entity.ACF.Density = (PhysObj:GetMass()*1000)/Entity.ACF.Volume
+
+ if Entity:IsPlayer() || Entity:IsNPC() then
+ Entity.ACF.Type = "Squishy"
+ elseif Entity:IsVehicle() then
+ Entity.ACF.Type = "Vehicle"
+ else
+ Entity.ACF.Type = "Prop"
+ end
+ --print(Entity.ACF.Health)
+end
+
+function ACF_Check ( Entity )
+
+ if not IsValid(Entity) then return false end
+
+ local physobj = Entity:GetPhysicsObject()
+ if not ( physobj:IsValid() and (physobj:GetMass() or 0)>0 and !Entity:IsWorld() and !Entity:IsWeapon() ) then return false end
+
+ local Class = Entity:GetClass()
+ if ( Class == "gmod_ghost" or Class == "debris" or Class == "prop_ragdoll" or string.find( Class , "func_" ) ) then return false end
+
+ if !Entity.ACF then
+ ACF_Activate( Entity )
+ elseif Entity.ACF.Mass != physobj:GetMass() then
+ ACF_Activate( Entity , true )
+ end
+ --print("ACF_Check "..Entity.ACF.Type)
+ return Entity.ACF.Type
+
+end
+
+function ACF_Damage ( Entity , Energy , FrAera , Angle , Inflictor , Bone, Gun, Type )
+
+ local Activated = ACF_Check( Entity )
+ local CanDo = hook.Run("ACF_BulletDamage", Activated, Entity, Energy, FrAera, Angle, Inflictor, Bone, Gun )
+ if CanDo == false or Activated == false then -- above (default) hook does nothing with activated
+ return { Damage = 0, Overkill = 0, Loss = 0, Kill = false }
+ end
+
+ if Entity.SpecialDamage then
+ return Entity:ACF_OnDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone, Type )
+ elseif Activated == "Prop" then
+
+ return ACF_PropDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
+
+ elseif Activated == "Vehicle" then
+
+ return ACF_VehicleDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone, Gun )
+
+ elseif Activated == "Squishy" then
+
+ return ACF_SquishyDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone, Gun )
+
+ end
+
+end
+
+function ACF_CalcDamage( Entity , Energy , FrAera , Angle )
+ local armor = Entity.ACF.Armour -- Armor
+ local losArmor = armor / math.abs( math.cos(math.rad(Angle)) ^ ACF.SlopeEffectFactor ) -- LOS Armor
+
+ local maxPenetration = (Energy.Penetration / FrAera) * ACF.KEtoRHA --RHA Penetration
+
+ local HitRes = {}
+
+
+
+
+
+
+
+ local dmul = 1--This actually controls overall prop damage from rounds. It should be in globals but i'm suck's at Coding's -karb
+
+ --BNK Stuff
+ if (ISBNK) then
+ local cvar = GetConVarNumber("sbox_godmode")
+
+ if (cvar == 1) then
+ dmul = 0
+ end
+ end
+ --SITP Stuff
+ --TODO: comment out ISSITP when not necessary
+ local var = 1
+ if (ISSITP) then
+ if(!Entity.sitp_spacetype) then
+ Entity.sitp_spacetype = "space"
+ end
+ if(Entity.sitp_spacetype != "space" and Entity.sitp_spacetype != "planet") then
+ var = 0
+ end
+ end
+
+ -- Projectile caliber. Messy, function signature
+ local caliber = 20 * ( FrAera^(1 / ACF.PenAreaMod) / 3.1416 )^(0.5)
+
+ -- Breach probability
+ local breachProb = math.Clamp((caliber / Entity.ACF.Armour - 1.3) / (7 - 1.3), 0, 1)
+
+ -- Penetration probability
+ local penProb = (math.Clamp(1 / (1 + math.exp(-43.9445 * (maxPenetration/losArmor - 1))), 0.0015, 0.9985) - 0.0015) / 0.997;
+
+ if breachProb > math.random() and maxPenetration > armor then -- Breach chance roll
+ HitRes.Damage = var * dmul * FrAera -- Inflicted Damage
+ HitRes.Overkill = maxPenetration - armor -- Remaining penetration
+ HitRes.Loss = armor / maxPenetration -- Energy loss in percents
+
+ return HitRes
+ elseif penProb > math.random() then -- Penetration chance roll
+ local Penetration = math.min( maxPenetration, losArmor )
+
+ HitRes.Damage = var * dmul * ( Penetration / losArmor )^2 * FrAera
+ HitRes.Overkill = (maxPenetration - Penetration)
+ HitRes.Loss = Penetration / maxPenetration
+
+ return HitRes
+ end
+
+ -- Projectile did not breach nor penetrate armor
+ local Penetration = math.min( maxPenetration , losArmor )
+
+ HitRes.Damage = var * dmul * ( Penetration / losArmor )^2 * FrAera
+ HitRes.Overkill = 0
+ HitRes.Loss = 1
+
+ return HitRes
+end
+
+function ACF_PropDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone )
+
+ local HitRes = ACF_CalcDamage( Entity , Energy , FrAera , Angle )
+
+
+ HitRes.Kill = false
+ if HitRes.Damage >= Entity.ACF.Health then
+ HitRes.Kill = true
+ else
+ Entity.ACF.Health = Entity.ACF.Health - HitRes.Damage
+ Entity.ACF.Armour = math.Clamp(Entity.ACF.MaxArmour * (0.5 + Entity.ACF.Health/Entity.ACF.MaxHealth/2)^1.7, Entity.ACF.MaxArmour*0.25, Entity.ACF.MaxArmour) --Simulating the plate weakening after a hit
+
+ --math.Clamp( Entity.ACF.Ductility, -0.8, 0.8 )
+ if Entity.ACF.PrHealth then
+ ACF_UpdateVisualHealth(Entity)
+ end
+ Entity.ACF.PrHealth = Entity.ACF.Health
+ end
+
+ return HitRes
+
+end
+
+function ACF_VehicleDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone, Gun )
+
+ local HitRes = ACF_CalcDamage( Entity , Energy , FrAera , Angle )
+
+ local Driver = Entity:GetDriver()
+ if Driver:IsValid() then
+ --if Ammo == true then
+ -- Driver.KilledByAmmo = true
+ --end
+ Driver:TakeDamage( HitRes.Damage*40 , Inflictor, Gun )
+ --if Ammo == true then
+ -- Driver.KilledByAmmo = false
+ --end
+
+ end
+
+ HitRes.Kill = false
+ if HitRes.Damage >= Entity.ACF.Health then
+ HitRes.Kill = true
+ else
+ Entity.ACF.Health = Entity.ACF.Health - HitRes.Damage
+ Entity.ACF.Armour = Entity.ACF.Armour * (0.5 + Entity.ACF.Health/Entity.ACF.MaxHealth/2) --Simulating the plate weakening after a hit
+ end
+
+ return HitRes
+end
+
+function ACF_SquishyDamage( Entity , Energy , FrAera , Angle , Inflictor , Bone, Gun)
+
+ local Size = Entity:BoundingRadius()
+ local Mass = Entity:GetPhysicsObject():GetMass()
+ local HitRes = {}
+ local Damage = 0
+ local Target = {ACF = {Armour = 0.1}} --We create a dummy table to pass armour values to the calc function
+ if (Bone) then
+
+ if ( Bone == 1 ) then --This means we hit the head
+ Target.ACF.Armour = Mass*0.02 --Set the skull thickness as a percentage of Squishy weight, this gives us 2mm for a player, about 22mm for an Antlion Guard. Seems about right
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle ) --This is hard bone, so still sensitive to impact angle
+ Damage = HitRes.Damage*20
+ if HitRes.Overkill > 0 then --If we manage to penetrate the skull, then MASSIVE DAMAGE
+ Target.ACF.Armour = Size*0.25*0.01 --A quarter the bounding radius seems about right for most critters head size
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
+ Damage = Damage + HitRes.Damage*100
+ end
+ Target.ACF.Armour = Mass*0.065 --Then to check if we can get out of the other side, 2x skull + 1x brains
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle )
+ Damage = Damage + HitRes.Damage*20
+
+ elseif ( Bone == 0 or Bone == 2 or Bone == 3 ) then --This means we hit the torso. We are assuming body armour/tough exoskeleton/zombie don't give fuck here, so it's tough
+ Target.ACF.Armour = Mass*0.08 --Set the armour thickness as a percentage of Squishy weight, this gives us 8mm for a player, about 90mm for an Antlion Guard. Seems about right
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle ) --Armour plate,, so sensitive to impact angle
+ Damage = HitRes.Damage*5
+ if HitRes.Overkill > 0 then
+ Target.ACF.Armour = Size*0.5*0.02 --Half the bounding radius seems about right for most critters torso size
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
+ Damage = Damage + HitRes.Damage*50 --If we penetrate the armour then we get into the important bits inside, so DAMAGE
+ end
+ Target.ACF.Armour = Mass*0.185 --Then to check if we can get out of the other side, 2x armour + 1x guts
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , Angle )
+
+ elseif ( Bone == 4 or Bone == 5 ) then --This means we hit an arm or appendage, so ormal damage, no armour
+
+ Target.ACF.Armour = Size*0.2*0.02 --A fitht the bounding radius seems about right for most critters appendages
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 ) --This is flesh, angle doesn't matter
+ Damage = HitRes.Damage*30 --Limbs are somewhat less important
+
+ elseif ( Bone == 6 or Bone == 7 ) then
+
+ Target.ACF.Armour = Size*0.2*0.02 --A fitht the bounding radius seems about right for most critters appendages
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 ) --This is flesh, angle doesn't matter
+ Damage = HitRes.Damage*30 --Limbs are somewhat less important
+
+ elseif ( Bone == 10 ) then --This means we hit a backpack or something
+
+ Target.ACF.Armour = Size*0.1*0.02 --Arbitrary size, most of the gear carried is pretty small
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 ) --This is random junk, angle doesn't matter
+ Damage = HitRes.Damage*2 --Damage is going to be fright and shrapnel, nothing much
+
+ else --Just in case we hit something not standard
+
+ Target.ACF.Armour = Size*0.2*0.02
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
+ Damage = HitRes.Damage*30
+
+ end
+
+ else --Just in case we hit something not standard
+
+ Target.ACF.Armour = Size*0.2*0.02
+ HitRes = ACF_CalcDamage( Target , Energy , FrAera , 0 )
+ Damage = HitRes.Damage*10
+
+ end
+
+ local dmul = 1
+
+ --BNK stuff
+ if (ISBNK) then
+ if(Entity.freq and Inflictor.freq) then
+ if (Entity != Inflictor) and (Entity.freq == Inflictor.freq) then
+ dmul = 0
+ end
+ end
+ end
+
+ --SITP stuff
+ local var = 1
+ if(!Entity.sitp_spacetype) then
+ Entity.sitp_spacetype = "space"
+ end
+ if(Entity.sitp_spacetype == "homeworld") then
+ var = 0
+ end
+
+ --if Ammo == true then
+ -- Entity.KilledByAmmo = true
+ --end
+ Entity:TakeDamage( Damage * dmul * var, Inflictor, Gun )
+ --if Ammo == true then
+ -- Entity.KilledByAmmo = false
+ --end
+
+ HitRes.Kill = false
+ --print(Damage)
+ --print(Bone)
+
+ return HitRes
+end
+
+----------------------------------------------------------
+-- Returns a table of all physically connected entities
+-- ignoring ents attached by only nocollides
+----------------------------------------------------------
+function ACF_GetAllPhysicalConstraints( ent, ResultTable )
+
+ local ResultTable = ResultTable or {}
+
+ if not IsValid( ent ) then return end
+ if ResultTable[ ent ] then return end
+
+ ResultTable[ ent ] = ent
+
+ local ConTable = constraint.GetTable( ent )
+
+ for k, con in ipairs( ConTable ) do
+
+ -- skip shit that is attached by a nocollide
+ if not (con.Type == "NoCollide") then
+ for EntNum, Ent in pairs( con.Entity ) do
+ ACF_GetAllPhysicalConstraints( Ent.Entity, ResultTable )
+ end
+ end
+
+ end
+
+ return ResultTable
+
+end
+
+-- for those extra sneaky bastards
+function ACF_GetAllChildren( ent, ResultTable )
+
+ local ResultTable = ResultTable or {}
+
+ if not IsValid( ent ) then return end
+ if ResultTable[ ent ] then return end
+
+ ResultTable[ ent ] = ent
+
+ local ChildTable = ent:GetChildren()
+
+ for k, v in pairs( ChildTable ) do
+
+ ACF_GetAllChildren( v, ResultTable )
+
+ end
+
+ return ResultTable
+
+end
diff --git a/lua/acf/server/sv_acfdamage.lua b/lua/acf/server/sv_acfdamage.lua
new file mode 100644
index 000000000..63360a252
--- /dev/null
+++ b/lua/acf/server/sv_acfdamage.lua
@@ -0,0 +1,658 @@
+-- This file is meant for the advanced damage functions used by the Armored Combat Framework
+
+-- optimization; reuse tables for ballistics traces
+local TraceRes = { }
+local TraceInit = { output = TraceRes }
+
+--[[----------------------------------------------------------------------------
+ Function:
+ ACF_HE
+ Arguments:
+ HitPos - detonation center,
+ FillerMass - mass of TNT being detonated in KG
+ FragMass - mass of the round casing for fragmentation purposes
+ Inflictor - owner of said TNT
+ NoOcc - table with entities to ignore
+ Gun - gun entity from which round is fired
+ Purpose:
+ Handles ACF explosions
+------------------------------------------------------------------------------]]
+function ACF_HE( Hitpos , HitNormal , FillerMass, FragMass, Inflictor, NoOcc, Gun )
+ local Power = FillerMass * ACF.HEPower --Power in KiloJoules of the filler mass of TNT
+ local Radius = (FillerMass)^0.33*8*39.37 --Scalling law found on the net, based on 1PSI overpressure from 1 kg of TNT at 15m
+ local MaxSphere = (4 * 3.1415 * (Radius*2.54 )^2) --Surface Aera of the sphere at maximum radius
+ local Amp = math.min(Power/2000,50)
+ util.ScreenShake( Hitpos, Amp, Amp, Amp/15, Radius*10 )
+ --debugoverlay.Sphere(Hitpos, Radius, 15, Color(255,0,0,32), 1) --developer 1 in console to see
+
+ local Targets = ents.FindInSphere( Hitpos, Radius )
+
+ local Fragments = math.max(math.floor((FillerMass/FragMass)*ACF.HEFrag),2)
+ local FragWeight = FragMass/Fragments
+ local FragVel = (Power*50000/FragWeight/Fragments)^0.5
+ local FragAera = (FragWeight/7.8)^0.33
+
+ local OccFilter = { NoOcc }
+ TraceInit.filter = OccFilter
+ local LoopKill = true
+
+ while LoopKill and Power > 0 do
+ LoopKill = false
+ local PowerSpent = 0
+ local Iterations = 0
+ local Damage = {}
+ local TotalAera = 0
+ for i,Tar in pairs(Targets) do
+ Iterations = i
+ if ( Tar != nil and Power > 0 and not Tar.Exploding ) then
+ local Type = ACF_Check(Tar)
+ if ( Type ) then
+ local Hitat = nil
+ if Type == "Squishy" then --A little hack so it doesn't check occlusion at the feet of players
+ local Eyes = Tar:LookupAttachment("eyes")
+ if Eyes then
+ Hitat = Tar:GetAttachment( Eyes )
+ if Hitat then
+ --Msg("Hitting Eyes\n")
+ Hitat = Hitat.Pos
+ else
+ Hitat = Tar:NearestPoint( Hitpos )
+ end
+ end
+ else
+ Hitat = Tar:NearestPoint( Hitpos )
+ end
+
+ --if hitpos inside hitbox of victim prop, nearest point doesn't work as intended
+ if Hitat == Hitpos then Hitat = Tar:GetPos() end
+
+ --[[see if we have a clean view to victim prop
+ local Occlusion = {}
+ Occlusion.start = Hitpos
+ Occlusion.endpos = Hitat + (Hitat-Hitpos):GetNormalized()*100
+ Occlusion.filter = OccFilter
+ Occlusion.mask = MASK_SOLID
+ local Occ = util.TraceLine( Occlusion )
+ ]]--
+
+ TraceInit.start = Hitpos
+ TraceInit.endpos = Hitat + (Hitat-Hitpos):GetNormalized()*100
+ TraceInit.filter = OccFilter
+ TraceInit.mask = MASK_SOLID
+
+ util.TraceLine( TraceInit ) -- automatically stored in output table: TraceRes
+
+ --[[
+ --retry for prop center if no hits at all, might have whiffed through bounding box and missed phys hull
+ --nearestpoint uses intersect of bbox from source point to origin (getpos), this is effectively just redoing the same thing
+ if ( !Occ.Hit and Hitpos != Hitat ) then
+ local Hitat = Tar:GetPos()
+ local Occlusion = {}
+ Occlusion.start = Hitpos
+ Occlusion.endpos = Hitat + (Hitat-Hitpos):GetNormalized()*100
+ Occlusion.filter = OccFilter
+ Occlusion.mask = MASK_SOLID
+ Occ = util.TraceLine( Occlusion )
+ end
+ --]]
+
+ if ( !TraceRes.Hit ) then
+ --no hit
+ elseif ( TraceRes.Hit and TraceRes.Entity:EntIndex() != Tar:EntIndex() ) then
+ --occluded, no hit
+ else
+ Targets[i] = nil --Remove the thing we just hit from the table so we don't hit it again in the next round
+ local Table = {}
+ Table.Ent = Tar
+ if Tar:GetClass() == "acf_engine" or Tar:GetClass() == "acf_ammo" or Tar:GetClass() == "acf_fueltank" then
+ Table.LocalHitpos = WorldToLocal(Hitpos, Angle(0,0,0), Tar:GetPos(), Tar:GetAngles())
+ end
+ Table.Dist = Hitpos:Distance(Tar:GetPos())
+ Table.Vec = (Tar:GetPos() - Hitpos):GetNormalized()
+ local Sphere = math.max(4 * 3.1415 * (Table.Dist*2.54 )^2,1) --Surface Aera of the sphere at the range of that prop
+ local AreaAdjusted = Tar.ACF.Aera
+ Table.Aera = math.min(AreaAdjusted/Sphere,0.5)*MaxSphere --Project the aera of the prop to the aera of the shadow it projects at the explosion max radius
+ table.insert(Damage, Table) --Add it to the Damage table so we know to damage it once we tallied everything
+ -- is it adding it too late?
+ TotalAera = TotalAera + Table.Aera
+ end
+ else
+ Targets[i] = nil --Target was invalid, so let's ignore it
+ table.insert( OccFilter , Tar ) -- updates the filter in TraceInit too
+ end
+ end
+ end
+
+ for i,Table in pairs(Damage) do
+
+ local Tar = Table.Ent
+ local Feathering = (1-math.min(1,Table.Dist/Radius)) ^ ACF.HEFeatherExp
+ local AeraFraction = Table.Aera/TotalAera
+ local PowerFraction = Power * AeraFraction --How much of the total power goes to that prop
+ local AreaAdjusted = (Tar.ACF.Aera / ACF.Threshold) * Feathering
+
+ local BlastRes
+ local Blast = {
+ --Momentum = PowerFraction/(math.max(1,Table.Dist/200)^0.05), --not used for anything
+ Penetration = PowerFraction^ACF.HEBlastPen*AreaAdjusted
+ }
+
+ local FragRes
+ local FragHit = Fragments * AeraFraction
+ local FragVel = math.max(FragVel - ( (Table.Dist/FragVel) * FragVel^2 * FragWeight^0.33/10000 )/ACF.DragDiv,0)
+ local FragKE = ACF_Kinetic( FragVel , FragWeight*FragHit, 1500 )
+ if FragHit < 0 then
+ if math.Rand(0,1) > FragHit then FragHit = 1 else FragHit = 0 end
+ end
+
+ -- erroneous HE penetration bug workaround; retries trace on crit ents after a short delay to ensure a hit.
+ -- we only care about hits on critical ents, saves on processing power
+ -- not going to re-use tables in the timer, shouldn't make too much difference
+ if Tar:GetClass() == "acf_engine" or Tar:GetClass() == "acf_ammo" or Tar:GetClass() == "acf_fueltank" then
+ timer.Simple(0.015*2, function()
+ if not IsValid(Tar) then return end
+
+ --recreate the hitpos and hitat, add slight jitter to hitpos and move it away some
+ local NewHitpos = LocalToWorld(Table.LocalHitpos + Table.LocalHitpos:GetNormalized()*3, Angle(math.random(),math.random(),math.random()), Tar:GetPos(), Tar:GetAngles())
+ local NewHitat = Tar:NearestPoint( NewHitpos )
+
+ local Occlusion = {
+ start = NewHitpos,
+ endpos = NewHitat + (NewHitat-NewHitpos):GetNormalized()*100,
+ filter = NoOcc,
+ mask = MASK_SOLID
+ }
+ local Occ = util.TraceLine( Occlusion )
+
+ if ( !Occ.Hit and NewHitpos != NewHitat ) then
+ local NewHitat = Tar:GetPos()
+ local Occlusion = {
+ start = NewHitpos,
+ endpos = NewHitat + (NewHitat-NewHitpos):GetNormalized()*100,
+ filter = NoOcc,
+ mask = MASK_SOLID
+ }
+ Occ = util.TraceLine( Occlusion )
+ end
+
+ if ( Occ.Hit and Occ.Entity:EntIndex() != Tar:EntIndex() ) then
+ --occluded, confirmed HE bug
+ --print("HE bug on "..Tar:GetClass()..", occluded by "..(Occ.Entity:GetModel()))
+ --debugoverlay.Sphere(Hitpos, 4, 20, Color(16,16,16,32), 1)
+ --debugoverlay.Sphere(NewHitpos,3,20,Color(0,255,0,32), true)
+ --debugoverlay.Sphere(NewHitat,3,20,Color(0,0,255,32), true)
+ elseif ( !Occ.Hit and NewHitpos != NewHitat ) then
+ --no hit, confirmed HE bug
+ --print("HE bug on "..Tar:GetClass())
+ else
+ --confirmed proper hit, apply damage
+ --print("No HE bug on "..Tar:GetClass())
+
+ BlastRes = ACF_Damage ( Tar , Blast , AreaAdjusted , 0 , Inflictor , 0 , Gun , "HE" )
+ FragRes = ACF_Damage ( Tar , FragKE , FragAera*FragHit , 0 , Inflictor , 0, Gun, "Frag" )
+ if (BlastRes and BlastRes.Kill) or (FragRes and FragRes.Kill) then
+ local Debris = ACF_HEKill( Tar, (Tar:GetPos() - NewHitpos):GetNormalized(), PowerFraction , Hitpos)
+ else
+ ACF_KEShove(Tar, NewHitpos, (Tar:GetPos() - NewHitpos):GetNormalized(), PowerFraction * 33.3 * (GetConVarNumber("acf_hepush") or 1) )
+ end
+ end
+ end)
+
+ --calculate damage that would be applied (without applying it), so HE deals correct damage to other props
+ BlastRes = ACF_CalcDamage( Tar, Blast, AreaAdjusted, 0 )
+ --FragRes = ACF_CalcDamage( Tar , FragKE , FragAera*FragHit , 0 ) --not used for anything in this case
+ else
+ BlastRes = ACF_Damage ( Tar , Blast , AreaAdjusted , 0 , Inflictor ,0 , Gun, "HE" )
+ FragRes = ACF_Damage ( Tar , FragKE , FragAera*FragHit , 0 , Inflictor , 0, Gun, "Frag" )
+ if (BlastRes and BlastRes.Kill) or (FragRes and FragRes.Kill) then
+ local Debris = ACF_HEKill( Tar , Table.Vec , PowerFraction , Hitpos )
+ table.insert( OccFilter , Debris ) --Add the debris created to the ignore so we don't hit it in other rounds
+ LoopKill = true --look for fresh targets since we blew a hole somewhere
+ else
+ ACF_KEShove(Tar, Hitpos, Table.Vec, PowerFraction * 33.3 * (GetConVarNumber("acf_hepush") or 1) ) --Assuming about 1/30th of the explosive energy goes to propelling the target prop (Power in KJ * 1000 to get J then divided by 33)
+ end
+ end
+ PowerSpent = PowerSpent + PowerFraction*BlastRes.Loss/2--Removing the energy spent killing props
+
+ end
+ Power = math.max(Power - PowerSpent,0)
+ end
+
+end
+
+function ACF_Spall( HitPos , HitVec , HitMask , KE , Caliber , Armour , Inflictor )
+
+ --if(!ACF.Spalling) then
+ if true then -- Folks say it's black magic and it kills their firstborns. So I had to disable it with more powerful magic.
+ return
+ end
+ local TotalWeight = 3.1416*(Caliber/2)^2 * Armour * 0.00079
+ local Spall = math.max(math.floor(Caliber*ACF.KEtoSpall),2)
+ local SpallWeight = TotalWeight/Spall
+ local SpallVel = (KE*2000/SpallWeight)^0.5/Spall
+ local SpallAera = (SpallWeight/7.8)^0.33
+ local SpallEnergy = ACF_Kinetic( SpallVel , SpallWeight, 600 )
+
+ --print(SpallWeight)
+ --print(SpallVel)
+
+ for i = 1,Spall do
+ local SpallTr = { }
+ SpallTr.start = HitPos
+ SpallTr.endpos = HitPos + (HitVec:GetNormalized()+VectorRand()/2):GetNormalized()*SpallVel
+ SpallTr.filter = HitMask
+
+ ACF_SpallTrace( HitVec , SpallTr , SpallEnergy , SpallAera , Inflictor )
+ end
+
+end
+
+function ACF_SpallTrace( HitVec , SpallTr , SpallEnergy , SpallAera , Inflictor )
+
+ local SpallRes = util.TraceLine(SpallTr)
+
+ if SpallRes.Hit and ACF_Check( SpallRes.Entity ) then
+
+ local Angle = ACF_GetHitAngle( SpallRes.HitNormal , HitVec )
+ local HitRes = ACF_Damage( SpallRes.Entity , SpallEnergy , SpallAera , Angle , Inflictor, 0 ) --DAMAGE !!
+ if HitRes.Kill then
+ ACF_APKill( SpallRes.Entity , HitVec:GetNormalized() , SpallEnergy.Kinetic )
+ end
+ if HitRes.Overkill > 0 then
+ table.insert( SpallTr.filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ SpallEnergy.Penetration = SpallEnergy.Penetration*(1-HitRes.Loss)
+ SpallEnergy.Momentum = SpallEnergy.Momentum*(1-HitRes.Loss)
+ ACF_SpallTrace( HitVec , SpallTr , SpallEnergy , SpallAera , Inflictor )
+ end
+ end
+end
+
+--Calculates the vector of the ricochet of a round upon impact at a set angle
+function ACF_RicochetVector(Flight, HitNormal)
+ local Vec = Flight:GetNormalized()
+
+ return Vec - ( 2 * Vec:Dot(HitNormal) ) * HitNormal
+end
+
+-- Handles the impact of a round on a target
+function ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+ Bullet.Ricochets = Bullet.Ricochets or 0
+ local Angle = ACF_GetHitAngle( HitNormal , Bullet["Flight"] )
+
+ local HitRes = ACF_Damage ( --DAMAGE !!
+ Target,
+ Energy,
+ Bullet["PenAera"],
+ Angle,
+ Bullet["Owner"],
+ Bone,
+ Bullet["Gun"],
+ Bullet["Type"]
+ )
+
+ local Ricochet = 0
+ if HitRes.Loss == 1 then
+ -- Ricochet distribution center
+ local sigmoidCenter = Bullet.DetonatorAngle or ( Bullet.Ricochet - math.abs(Speed / 39.37 - Bullet.LimitVel) / 100 )
+
+ -- Ricochet probability (sigmoid distribution); up to 5% minimal ricochet probability for projectiles with caliber < 20 mm
+ local ricoProb = math.Clamp( 1 / (1 + math.exp( (Angle - sigmoidCenter) / -4) ), math.max(-0.05 * (Bullet.Caliber - 2) / 2, 0), 1 )
+
+ -- Checking for ricochet
+ if ricoProb > math.random() and Angle < 90 then
+ Ricochet = math.Clamp(Angle / 90, 0.05, 1) -- atleast 5% of energy is kept
+ HitRes.Loss = 0.25 - Ricochet
+ Energy.Kinetic = Energy.Kinetic * HitRes.Loss
+ end
+ end
+
+ ACF_KEShove(
+ Target,
+ HitPos,
+ Bullet["Flight"]:GetNormalized(),
+ Energy.Kinetic * HitRes.Loss * 1000 * Bullet["ShovePower"] * (GetConVarNumber("acf_recoilpush") or 1)
+ )
+
+ if HitRes.Kill then
+ local Debris = ACF_APKill( Target , (Bullet["Flight"]):GetNormalized() , Energy.Kinetic )
+ table.insert( Bullet["Filter"] , Debris )
+ end
+
+ HitRes.Ricochet = false
+ if Ricochet > 0 and Bullet.Ricochets < 3 then
+ Bullet.Ricochets = Bullet.Ricochets + 1
+ Bullet["Pos"] = HitPos + HitNormal * 0.75
+ Bullet.FlightTime = 0
+ Bullet.Flight = (ACF_RicochetVector(Bullet.Flight, HitNormal) + VectorRand()*0.025):GetNormalized() * Speed * Ricochet
+ Bullet.TraceBackComp = math.max(ACF_GetPhysicalParent(Target):GetPhysicsObject():GetVelocity():Dot(Bullet["Flight"]:GetNormalized()),0)
+ HitRes.Ricochet = true
+ end
+
+ return HitRes
+end
+
+function ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ Bullet.GroundRicos = Bullet.GroundRicos or 0
+ local MaxDig = ((Energy.Penetration/Bullet.PenAera)*ACF.KEtoRHA/ACF.GroundtoRHA)/25.4
+ local HitRes = {Penetrated = false, Ricochet = false}
+
+ local DigTr = { }
+ DigTr.start = HitPos + Bullet.Flight:GetNormalized()*0.1
+ DigTr.endpos = HitPos + Bullet.Flight:GetNormalized()*(MaxDig+0.1)
+ DigTr.filter = Bullet.Filter
+ DigTr.mask = MASK_SOLID_BRUSHONLY
+ local DigRes = util.TraceLine(DigTr)
+ --print(util.GetSurfacePropName(DigRes.SurfaceProps))
+
+ local loss = DigRes.FractionLeftSolid
+
+ if loss == 1 or loss == 0 then --couldn't penetrate
+ local Ricochet = 0
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Angle = ACF_GetHitAngle( HitNormal, Bullet.Flight )
+ local MinAngle = math.min(Bullet.Ricochet - Speed/39.37/30 + 20,89.9) --Making the chance of a ricochet get higher as the speeds increase
+ if Angle > math.random(MinAngle,90) and Angle < 89.9 then --Checking for ricochet
+ Ricochet = Angle/90*0.75
+ end
+
+ if Ricochet > 0 and Bullet.GroundRicos < 2 then
+ Bullet.GroundRicos = Bullet.GroundRicos + 1
+ Bullet.Pos = HitPos + HitNormal * 1
+ Bullet.Flight = (ACF_RicochetVector(Bullet.Flight, HitNormal) + VectorRand()*0.05):GetNormalized() * Speed * Ricochet
+ HitRes.Ricochet = true
+ end
+ else --penetrated
+ Bullet.Flight = Bullet.Flight * (1 - loss)
+ Bullet.Pos = DigRes.StartPos + Bullet.Flight:GetNormalized() * 0.25 --this is actually where trace left brush
+ HitRes.Penetrated = true
+ end
+
+ return HitRes
+end
+
+function ACF_KEShove(Target, Pos, Vec, KE )
+ local CanDo = hook.Run("ACF_KEShove", Target, Pos, Vec, KE )
+ if CanDo == false then return end
+
+ local parent = ACF_GetPhysicalParent(Target)
+ local phys = parent:GetPhysicsObject()
+
+ if (phys:IsValid()) then
+ if(!Target.acflastupdatemass) or ((Target.acflastupdatemass + 10) < CurTime()) then
+ ACF_CalcMassRatio(Target)
+ end
+ if not Target.acfphystotal then return end --corner case error check
+ local physratio = Target.acfphystotal / Target.acftotal
+ phys:ApplyForceOffset( Vec:GetNormalized() * KE * physratio, Pos )
+ end
+end
+
+
+-- whitelist for things that can be turned into debris
+ACF.Debris = {
+ acf_ammo = true,
+ acf_gun = true,
+ acf_gearbox = true,
+ acf_fueltank = true,
+ acf_engine = true,
+ prop_physics = true,
+ prop_vehicle_prisoner_pod = true
+}
+
+-- things that should have scaledexplosion called on them instead of being turned into debris
+ACF.Splosive = {
+ acf_ammo = true,
+ acf_fueltank = true
+}
+
+-- helper function to process children of an acf-destroyed prop
+-- AP will HE-kill children props like a detonation; looks better than a directional spray of unrelated debris from the AP kill
+local function ACF_KillChildProps( Entity, BlastPos, Energy )
+
+ local count = 0
+ local boom = {}
+ local children = ACF_GetAllChildren(Entity)
+
+ -- do an initial processing pass on children, separating out explodey things to handle last
+ for _, ent in pairs( children ) do
+ ent.ACF_Killed = true -- mark that it's already processed
+ local class = ent:GetClass()
+ if not ACF.Debris[class] then
+ children[ent] = nil -- ignoring stuff like holos
+ else
+ ent:SetParent(nil)
+ if ACF.Splosive[class] then
+ table.insert(boom, ent) -- keep track of explosives to make them boom last
+ children[ent] = nil
+ else
+ count = count+1 -- can't use #table or :count() because of ent indexing...
+ end
+ end
+ end
+
+ -- HE kill the children of this ent, instead of disappearing them by removing parent
+ if count > 0 then
+ local DebrisChance = math.Clamp(ACF.ChildDebris/count, 0, 1)
+ local power = Energy/math.min(count,3)
+
+ for _, child in pairs( children ) do
+ if IsValid(child) then
+ if math.random() < DebrisChance then -- ignore some of the debris props to save lag
+ ACF_HEKill( child, (child:GetPos() - BlastPos):GetNormalized(), power )
+ else
+ constraint.RemoveAll( child )
+ child:Remove()
+ end
+ end
+ end
+ end
+
+ -- explode stuff last, so we don't re-process all that junk again in a new explosion
+ if #boom > 0 then
+ for _, child in pairs( boom ) do
+ if not IsValid(child) or child.Exploding then continue end
+ child.Exploding = true
+ ACF_ScaledExplosion( child ) -- explode any crates that are getting removed
+ end
+ end
+
+end
+
+-- blast pos is an optional world-pos input for flinging away children props more realistically
+function ACF_HEKill( Entity , HitVector , Energy , BlastPos )
+
+ -- if it hasn't been processed yet, check for children
+ if not Entity.ACF_Killed then
+ ACF_KillChildProps( Entity, BlastPos or Entity:GetPos(), Energy )
+ end
+
+ -- process this prop into debris
+ local entClass = Entity:GetClass()
+ local obj = Entity:GetPhysicsObject()
+ local grav = true
+ local mass = 25
+ if obj:IsValid() then
+ mass = math.max(obj:GetMass(), mass)
+ if ISSITP then
+ grav = obj:IsGravityEnabled()
+ end
+ end
+
+ constraint.RemoveAll( Entity )
+ Entity:Remove()
+
+ if(Entity:BoundingRadius() < ACF.DebrisScale) then
+ return nil
+ end
+
+ local Debris = ents.Create( "Debris" )
+ Debris:SetModel( Entity:GetModel() )
+ Debris:SetAngles( Entity:GetAngles() )
+ Debris:SetPos( Entity:GetPos() )
+ Debris:SetMaterial("models/props_wasteland/metal_tram001a")
+ Debris:Spawn()
+
+ if math.random() < ACF.DebrisIgniteChance then
+ Debris:Ignite(math.Rand(5,45),0)
+ end
+
+ Debris:Activate()
+
+ local phys = Debris:GetPhysicsObject()
+ if phys:IsValid() then
+ phys:SetMass(mass)
+ phys:ApplyForceOffset( HitVector:GetNormalized() * Energy * 10 , Debris:GetPos()+VectorRand()*20 ) -- previously energy*350
+ phys:EnableGravity( grav )
+ end
+
+ return Debris
+
+end
+
+function ACF_APKill( Entity , HitVector , Power )
+
+ -- kill the children of this ent, instead of disappearing them from removing parent
+ ACF_KillChildProps( Entity, Entity:GetPos(), Power )
+
+ constraint.RemoveAll( Entity )
+ Entity:Remove()
+
+ if(Entity:BoundingRadius() < ACF.DebrisScale) then
+ return nil
+ end
+
+ local Debris = ents.Create( "Debris" )
+ Debris:SetModel( Entity:GetModel() )
+ Debris:SetAngles( Entity:GetAngles() )
+ Debris:SetPos( Entity:GetPos() )
+ Debris:SetMaterial(Entity:GetMaterial())
+ Debris:SetColor(Color(120,120,120,255))
+ Debris:Spawn()
+ Debris:Activate()
+
+ local BreakEffect = EffectData()
+ BreakEffect:SetOrigin( Entity:GetPos() )
+ BreakEffect:SetScale( 20 )
+ util.Effect( "WheelDust", BreakEffect )
+
+ local phys = Debris:GetPhysicsObject()
+ if (phys:IsValid()) then
+ phys:ApplyForceOffset( HitVector:GetNormalized() * Power * 350 , Debris:GetPos()+VectorRand()*20 )
+ end
+
+ return Debris
+
+end
+
+--converts what would be multiple simultaneous cache detonations into one large explosion
+function ACF_ScaledExplosion( ent )
+ local Inflictor = nil
+ if( ent.Inflictor ) then
+ Inflictor = ent.Inflictor
+ end
+
+ local HEWeight
+ if ent:GetClass() == "acf_fueltank" then
+ HEWeight = (math.max(ent.Fuel, ent.Capacity * 0.0025) / ACF.FuelDensity[ent.FuelType]) * 0.1
+ else
+ local HE, Propel
+ if ent.RoundType == "Refill" then
+ HE = 0.001
+ Propel = 0.001
+ else
+ HE = ent.BulletData["FillerMass"] or 0
+ Propel = ent.BulletData["PropMass"] or 0
+ end
+ HEWeight = (HE+Propel*(ACF.PBase/ACF.HEPower))*ent.Ammo
+ end
+ local Radius = HEWeight^0.33*8*39.37
+ local ExplodePos = {}
+ local Pos = ent:LocalToWorld(ent:OBBCenter())
+ table.insert(ExplodePos, Pos)
+ local LastHE = 0
+
+ local Search = true
+ local Filter = {ent}
+ while Search do
+ for key,Found in pairs(ents.FindInSphere(Pos, Radius)) do
+ if Found.IsExplosive and not Found.Exploding then
+ local Hitat = Found:NearestPoint( Pos )
+
+ local Occlusion = {}
+ Occlusion.start = Pos
+ Occlusion.endpos = Hitat
+ Occlusion.filter = Filter
+ local Occ = util.TraceLine( Occlusion )
+
+ if ( Occ.Fraction == 0 ) then
+ table.insert(Filter,Occ.Entity)
+ local Occlusion = {}
+ Occlusion.start = Pos
+ Occlusion.endpos = Hitat
+ Occlusion.filter = Filter
+ Occ = util.TraceLine( Occlusion )
+ --print("Ignoring nested prop")
+ end
+
+ if ( Occ.Hit and Occ.Entity:EntIndex() != Found.Entity:EntIndex() ) then
+ --Msg("Target Occluded\n")
+ else
+ local FoundHEWeight
+ if Found:GetClass() == "acf_fueltank" then
+ FoundHEWeight = (math.max(Found.Fuel, Found.Capacity * 0.0025) / ACF.FuelDensity[Found.FuelType]) * 0.1
+ else
+ local HE, Propel
+ if Found.RoundType == "Refill" then
+ HE = 0.001
+ Propel = 0.001
+ else
+ HE = Found.BulletData["FillerMass"] or 0
+ Propel = Found.BulletData["PropMass"] or 0
+ end
+ FoundHEWeight = (HE+Propel*(ACF.PBase/ACF.HEPower))*Found.Ammo
+ end
+
+ table.insert(ExplodePos, Found:LocalToWorld(Found:OBBCenter()))
+ HEWeight = HEWeight + FoundHEWeight
+ Found.IsExplosive = false
+ Found.DamageAction = false
+ Found.KillAction = false
+ Found.Exploding = true
+ table.insert(Filter,Found)
+ Found:Remove()
+ end
+ end
+ end
+
+ if HEWeight > LastHE then
+ Search = true
+ LastHE = HEWeight
+ Radius = (HEWeight)^0.33*8*39.37
+ else
+ Search = false
+ end
+
+ end
+
+ local totalpos = Vector()
+ for _, cratepos in pairs(ExplodePos) do totalpos = totalpos + cratepos end
+ local AvgPos = totalpos / #ExplodePos
+
+ ent:Remove()
+ ACF_HE( AvgPos , Vector(0,0,1) , HEWeight , HEWeight*0.5 , Inflictor , ent, ent )
+
+ local Flash = EffectData()
+ Flash:SetOrigin( AvgPos )
+ Flash:SetNormal( Vector(0,0,-1) )
+ Flash:SetRadius( math.max( Radius, 1 ) )
+ util.Effect( "ACF_Scaled_Explosion", Flash )
+end
+
+function ACF_GetHitAngle( HitNormal , HitVector )
+
+ HitVector = HitVector*-1
+ local Angle = math.min(math.deg(math.acos(HitNormal:Dot( HitVector:GetNormalized() ) ) ),89.999 )
+ --Msg("Angle : " ..Angle.. "\n")
+ return Angle
+
+end
diff --git a/lua/acf/server/sv_acfpermission.lua b/lua/acf/server/sv_acfpermission.lua
new file mode 100644
index 000000000..aceb3dc44
--- /dev/null
+++ b/lua/acf/server/sv_acfpermission.lua
@@ -0,0 +1,692 @@
+// This file defines damage permission with all ACF weaponry
+
+ACF = ACF or {}
+ACF.Permissions = {}
+local this = ACF.Permissions
+
+//TODO: make player-customizable
+this.Selfkill = true
+
+this.Safezones = false
+
+this.Player = {}
+this.Modes = {}
+this.ModeDescs = {}
+this.ModeThinks = {}
+
+//TODO: convar this
+local mapSZDir = "acf/safezones/"
+local mapDPMDir = "acf/permissions/"
+file.CreateDir(mapDPMDir)
+
+
+
+local function msgtoconsole(hud, msg)
+ print(msg)
+end
+
+
+
+
+local function resolveAABBs(mins, maxs)
+
+ /*
+ for xyz, val in pairs(mins) do // ensuring points conform to AABB mins/maxs
+ if val > maxs.xyz then
+ local store = maxs.xyz
+ maxs.xyz = val
+ mins.xyz = store
+ end
+ end
+ //*/
+
+ local store
+ if mins.x > maxs.x then
+ store = maxs.x
+ maxs.x = mins.x
+ mins.x = store
+ end
+
+ if mins.y > maxs.y then
+ store = maxs.y
+ maxs.y = mins.y
+ mins.y = store
+ end
+
+ if mins.z > maxs.z then
+ store = maxs.z
+ maxs.z = mins.z
+ mins.z = store
+ end
+
+ return mins, maxs
+end
+
+
+//TODO: sanitize safetable instead of marking it all as bad
+local function validateSZs(safetable)
+ if type(safetable) ~= "table" then return false end
+
+ --PrintTable(safetable)
+
+ for k, v in pairs(safetable) do
+ if type(k) ~= "string" then return false end
+ if not (#v == 2 and v[1] and v[2]) then return false end
+
+ for a, b in ipairs(v) do
+ if not (b.x and b.y and b.z) then return false end
+ end
+
+ local mins = v[1]
+ local maxs = v[2]
+
+ mins, maxs = resolveAABBs(mins, maxs)
+
+ end
+
+ return true
+end
+
+
+
+
+local function getMapFilename()
+
+ local mapname = string.gsub(game.GetMap(), "[^%a%d-_]", "_")
+ return mapSZDir .. mapname .. ".txt"
+
+end
+
+
+
+local function getMapSZs()
+ local mapname = getMapFilename()
+ local mapSZFile = file.Read(mapname, "DATA") or ""
+
+ local safezones = util.JSONToTable(mapSZFile)
+
+ if not validateSZs(safezones) then
+ // TODO: generate default safezones around spawnpoints.
+ return false
+ end
+
+ this.Safezones = safezones
+ return true
+end
+
+
+local function SaveMapDPM(mode)
+ local mapname = string.gsub(game.GetMap(), "[^%a%d-_]", "_")
+ file.Write(mapDPMDir .. mapname .. ".txt", mode)
+end
+
+local function LoadMapDPM()
+ local mapname = string.gsub(game.GetMap(), "[^%a%d-_]", "_")
+ return file.Read(mapDPMDir .. mapname .. ".txt", "DATA")
+end
+
+
+hook.Add( "Initialize", "ACF_LoadSafesForMap", function()
+ if not getMapSZs() then
+ print("!!!!!!!!!!!!!!!!!!\nWARNING: Safezone file " .. getMapFilename() .. " is missing, invalid or corrupt! Safezones will not be restored this time.\n!!!!!!!!!!!!!!!!!!")
+ end
+end )
+
+
+local plyzones = {}
+hook.Add("Think", "ACF_DetectSZTransition", function()
+ for k, ply in pairs(player.GetAll()) do
+ local sid = ply:SteamID()
+ local trans = false
+ local pos = ply:GetPos()
+ local oldzone = plyzones[sid]
+
+ local zone = this.IsInSafezone(pos) or nil
+ plyzones[sid] = zone
+
+ if oldzone ~= zone then
+ hook.Call("ACF_PlayerChangedZone", GAMEMODE, ply, zone, oldzone)
+ end
+ end
+end)
+
+
+concommand.Add( "ACF_AddSafeZone", function(ply, cmd, args, str)
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if not args[1] then printmsg(HUD_PRINTCONSOLE,
+ " - Add a safezone as an AABB box." ..
+ "\n Input a name and six numbers. First three numbers are minimum co-ords, last three are maxs." ..
+ "\n Example; ACF_addsafezone airbase -500 -500 0 500 500 1000")
+ return false
+ end
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ local szname = tostring(args[1])
+ args[1] = nil
+ local default = tostring(args[8])
+ if default ~= "default" then default = nil end
+
+ if not this.Safezones then this.Safezones = {} end
+
+ if this.Safezones[szname] and this.Safezones[szname].default then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: an unmodifiable safezone called " .. szname .. " already exists!")
+ return false
+ end
+
+ for k, v in ipairs(args) do
+ args[k] = tonumber(v)
+ if args[k] == nil then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: argument " .. k .. " could not be interpreted as a number (" .. v .. ")")
+ return false
+ end
+ end
+
+ local mins = Vector(args[2], args[3], args[4])
+ local maxs = Vector(args[5], args[6], args[7])
+ mins, maxs = resolveAABBs(mins, maxs)
+
+ this.Safezones[szname] = {mins, maxs}
+ if default then this.Safezones[szname].default = true end
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: added a safezone called " .. szname .. " between " .. tostring(mins) .. " and " .. tostring(maxs) .. "!")
+ return true
+ end
+end)
+
+
+
+
+concommand.Add( "ACF_RemoveSafeZone", function(ply, cmd, args, str)
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if not args[1] then printmsg(HUD_PRINTCONSOLE,
+ " - Delete a safezone using its name." ..
+ "\n Input a safezone name. If it exists, it will be removed." ..
+ "\n Deletion is not permanent until safezones are saved.")
+ return false
+ end
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ local szname = tostring(args[1])
+ if not szname then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: could not interpret your input as a string.")
+ return false
+ end
+
+ if not (this.Safezones and this.Safezones[szname]) then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: could not find a safezone called " .. szname .. ".")
+ return false
+ end
+
+ if this.Safezones[szname].default then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: an unmodifiable safezone called " .. szname .. " already exists!")
+ return false
+ end
+
+ this.Safezones[szname] = nil
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: removed the safezone called " .. szname .. "!")
+ return true
+ end
+end)
+
+
+concommand.Add( "ACF_SaveSafeZones", function(ply, cmd, args, str)
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ if not this.Safezones then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: There are no safezones on the map which can be saved.")
+ return false
+ end
+
+ local szjson = util.TableToJSON(this.Safezones)
+
+ local mapname = getMapFilename()
+ file.CreateDir(mapSZDir)
+ file.Write(mapname, szjson)
+
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: All safezones on the map have been made restorable.")
+ return true
+ end
+end)
+
+
+concommand.Add( "ACF_ReloadSafeZones", function(ply, cmd, args, str)
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ local ret = getMapSZs()
+
+ if ret then
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: All safezones on the map have been restored.")
+ else
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: Safezone file for this map is missing, invalid or corrupt.")
+ end
+ return ret
+ end
+end)
+
+
+concommand.Add( "ACF_SetPermissionMode", function(ply, cmd, args, str)
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if not args[1] then
+ local modes = ""
+ for k, v in pairs(this.Modes) do
+ modes = modes .. k .. " "
+ end
+ printmsg(HUD_PRINTCONSOLE,
+ " - Set damage permission behaviour mode." ..
+ "\n Available modes: " .. modes)
+ return false
+ end
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ local mode = tostring(args[1])
+ if not this.Modes[mode] then
+ printmsg(HUD_PRINTCONSOLE,
+ "Command unsuccessful: " .. mode .. " is not a valid permission mode!" ..
+ "\nUse this command without arguments to see all available modes.")
+ return false
+ end
+
+ local oldmode = table.KeyFromValue(this.Modes, this.DamagePermission)
+ this.DamagePermission = this.Modes[mode]
+
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: Current damage permission policy is now " .. mode .. "!")
+
+ hook.Call("ACF_ProtectionModeChanged", GAMEMODE, mode, oldmode)
+
+ return true
+ end
+end)
+
+concommand.Add( "ACF_SetDefaultPermissionMode", function(ply, cmd, args, str)
+
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if not args[1] then
+ local modes = ""
+ for k, v in pairs(this.Modes) do
+ modes = modes .. k .. " "
+ end
+ printmsg(HUD_PRINTCONSOLE,
+ " - Set damage permission behaviour mode." ..
+ "\n Available modes: " .. modes)
+ return false
+ end
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ local mode = tostring(args[1])
+ if not this.Modes[mode] then
+ printmsg(HUD_PRINTCONSOLE,
+ "Command unsuccessful: " .. mode .. " is not a valid permission mode!" ..
+ "\nUse this command without arguments to see all available modes.")
+ return false
+ end
+
+ if this.DefaultPermission == mode then return false end
+
+ SaveMapDPM(mode)
+ this.DefaultPermission = mode
+
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: Default permission mode for "..game.GetMap().." set to: "..mode)
+
+ for k,v in pairs(player.GetAll()) do
+ if v:IsAdmin() then
+ v:SendLua("chat.AddText(Color(255,0,0),\"Default permission mode for "..game.GetMap().." has been set to " .. mode .. "!\")")
+ end
+ end
+
+ this.ResendPermissionsOnChanged()
+ return true
+ end
+end)
+
+
+concommand.Add( "ACF_ReloadPermissionModes", function(ply, cmd, args, str)
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ if not aaa_IncludeHere then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: folder-loading function is not available.")
+ return false
+ end
+
+ aaa_IncludeHere("ACF/server/permissionmodes")
+
+ local mode = table.KeyFromValue(this.Modes, this.DamagePermission)
+
+ if not mode then
+ this.DamagePermission = function() end
+ hook.Call("ACF_ProtectionModeChanged", GAMEMODE, "default", nil)
+ mode = "default"
+ end
+
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: Current damage permission policy is now " .. mode .. "!")
+ return true
+ end
+end)
+
+
+
+local function tellPlysAboutDPMode(mode, oldmode)
+ if mode == oldmode then return end
+
+ for k, v in pairs(player.GetAll()) do
+ v:SendLua("chat.AddText(Color(255,0,0),\"Damage protection has been changed to " .. mode .. " mode!\")")
+ end
+end
+hook.Add("ACF_ProtectionModeChanged", "ACF_TellPlysAboutDPMode", tellPlysAboutDPMode)
+
+
+
+
+function this.IsInSafezone(pos)
+
+ if not this.Safezones then return false end
+
+ local szmin, szmax
+ for szname, szpts in pairs(this.Safezones) do
+ szmin = szpts[1]
+ szmax = szpts[2]
+
+ if (pos.x > szmin.x and pos.y > szmin.y and pos.z > szmin.z) and
+ (pos.x < szmax.x and pos.y < szmax.y and pos.z < szmax.z) then
+ return szname
+ end
+ end
+ return false
+end
+
+
+
+function this.RegisterMode(mode, name, desc, default, think, defaultaction)
+
+ this.Modes[name] = mode
+ this.ModeDescs[name] = desc
+ this.ModeThinks[name] = think or function() end
+ this.DefaultCanDamage = defaultaction or false
+ print("ACF: Registered damage permission mode \"" .. name .. "\"!")
+
+ local DPM = LoadMapDPM()
+
+ if DPM ~= nil then
+ if DPM == name then
+ print("ACF: Found default permission mode: " .. DPM)
+ print("ACF: Setting permission mode to: " .. name)
+ this.DamagePermission = this.Modes[name]
+ this.DefaultPermission = name
+ end
+ else
+ if default then
+ print("ACF: Map does not have default permission set, using default")
+ print("ACF: Setting permission mode to: " .. name)
+ this.DamagePermission = this.Modes[name]
+ this.DefaultPermission = name
+ end
+ end
+
+ --Old method - can break on rare occasions!
+ --if LoadMapDPM() == name or default then
+ -- print("ACF: Setting permission mode to: "..name)
+ -- this.DamagePermission = this.Modes[name]
+ -- this.DefaultPermission = name
+ --end
+end
+
+
+
+function this.CanDamage(Type, Entity, Energy, FrAera, Angle, Inflictor, Bone, Gun)
+ local owner = CPPI and Entity:CPPIGetOwner() or Entity:GetOwner()
+
+ if not (IsValid(owner) and owner:IsPlayer()) then
+ if IsValid(Entity) and Entity:IsPlayer() then
+ owner = Entity
+ else
+ if this.DefaultCanDamage then return
+ else return this.DefaultCanDamage end
+ end
+ end
+
+ if not (IsValid(Inflictor) and Inflictor:IsPlayer()) then
+ if this.DefaultCanDamage then return
+ else return this.DefaultCanDamage end
+ end
+
+ return this.DamagePermission(owner, Inflictor, Entity)
+end
+hook.Add("ACF_BulletDamage", "ACF_DamagePermissionCore", this.CanDamage)
+
+
+
+this.thinkWrapper = function()
+ local curmode = table.KeyFromValue(this.Modes, this.DamagePermission)
+ --print(curmode)
+ local think = this.ModeThinks[curmode]
+ local nextthink
+
+ if think then
+ nextthink = think()
+ end
+
+ timer.Simple(nextthink or 0.01, this.thinkWrapper)
+end
+
+timer.Simple(0.01, this.thinkWrapper)
+
+
+function this.GetDamagePermissions(ownerid)
+ if not this.Player[ownerid] then
+ this.Player[ownerid] = {[ownerid] = true}
+ end
+
+ return this.Player[ownerid]
+end
+
+
+function this.AddDamagePermission(owner, attacker)
+ local ownerid = owner:SteamID()
+ local attackerid = attacker:SteamID()
+
+ local ownerprefs = this.GetDamagePermissions(ownerid)
+
+ ownerprefs[attackerid] = true
+end
+
+
+function this.RemoveDamagePermission(owner, attacker)
+ local ownerid = owner:SteamID()
+ if not this.Player[ownerid] then return end
+
+ local attackerid = attacker:SteamID()
+ this.Player[ownerid][attackerid] = nil
+end
+
+
+function this.ClearDamagePermissions(owner)
+ local ownerid = owner:SteamID()
+ if not this.Player[ownerid] then return end
+
+ this.Player[ownerid] = nil
+end
+
+
+function this.PermissionsRaw(ownerid, attackerid, value)
+ if not ownerid then return end
+
+ local ownerprefs = this.GetDamagePermissions(ownerid)
+
+ if attackerid then
+ local old = ownerprefs[attackerid] and true or nil
+ local new = value and true or nil
+ ownerprefs[attackerid] = new
+ return old != new
+ end
+
+ return false
+end
+
+
+local function onDisconnect( ply )
+ plyid = ply:SteamID()
+
+ if this.Player[plyid] then
+ this.Player[plyid] = nil
+ end
+
+ plyzones[plyid] = nil
+end
+hook.Add( "PlayerDisconnected", "ACF_PermissionDisconnect", onDisconnect )
+
+
+
+
+local function plyBySID(steamid)
+ for k, v in pairs(player.GetAll()) do
+ if v:SteamID() == steamid then
+ return v
+ end
+ end
+
+ return false
+end
+
+
+
+
+-- -- -- -- -- Client sync -- -- -- -- --
+
+// All code below modified from the NADMOD client permissions menu, by Nebual
+// http://www.facepunch.com/showthread.php?t=1221183
+util.AddNetworkString("ACF_dmgfriends")
+util.AddNetworkString("ACF_refreshfeedback")
+net.Receive("ACF_dmgfriends", function(len, ply)
+ //Msg("\nsv dmgfriends\n")
+ if not ply:IsValid() then return end
+
+ local perms = net.ReadTable()
+ local ownerid = ply:SteamID()
+
+ //Msg("ownerid = ", ownerid)
+ //PrintTable(perms)
+
+ local changed
+ for k, v in pairs(perms) do
+ changed = this.PermissionsRaw(ownerid, k, v)
+ //Msg(k, " has ", changed and "changed\n" or "not changed\n")
+
+ if changed then
+ local targ = plyBySID(k)
+ if targ then
+ local note = v and "given you" or "removed your"
+ //Msg("Sending", targ, " ", note, "\n")
+ targ:SendLua( string.format( "GAMEMODE:AddNotify(%q,%s,7)", ply:Nick() .. " has " .. note .. " permission to damage their objects with ACF!", "NOTIFY_GENERIC" ) )
+ end
+ end
+ end
+
+ net.Start("ACF_refreshfeedback")
+ net.WriteBit(true)
+ net.Send(ply)
+
+end)
+
+
+
+
+function this.RefreshPlyDPFriends(ply)
+ //Msg("\nsv refreshfriends\n")
+ if not ply:IsValid() then return end
+
+ local perms = this.GetDamagePermissions(ply:SteamID())
+
+ net.Start("ACF_refreshfriends")
+ net.WriteTable(perms)
+ net.Send(ply)
+end
+util.AddNetworkString("ACF_refreshfriends")
+net.Receive("ACF_refreshfriends", function(len, ply) this.RefreshPlyDPFriends(ply) end)
+
+
+
+
+function this.SendPermissionsState(ply)
+
+ local modes = this.ModeDescs
+ local current = table.KeyFromValue(this.Modes, this.DamagePermission)
+
+ net.Start("ACF_refreshpermissions")
+ net.WriteTable(modes)
+ net.WriteString(current or this.DefaultPermission)
+ net.WriteString(this.DefaultPermission or "")
+ net.Send(ply)
+end
+util.AddNetworkString("ACF_refreshpermissions")
+net.Receive("ACF_refreshpermissions", function(len, ply) this.SendPermissionsState(ply) end)
+
+
+
+
+function this.ResendPermissionsOnChanged()
+ for k, ply in pairs(player.GetAll()) do
+ this.SendPermissionsState(ply)
+ end
+end
+hook.Add("ACF_ProtectionModeChanged", "ACF_ResendPermissionsOnChanged", this.ResendPermissionsOnChanged)
+
+
+
+
+-- -- -- -- -- Initial DP mode load -- -- -- -- --
+
+if not aaa_IncludeHere then
+ this.DamagePermission = function() end
+ hook.Call("ACF_ProtectionModeChanged", GAMEMODE, "default", nil)
+ mode = "default"
+else
+ aaa_IncludeHere("ACF/server/permissionmodes")
+
+ local mode = table.KeyFromValue(this.Modes, this.DamagePermission)
+
+ if not mode then
+ this.DamagePermission = function() end
+ hook.Call("ACF_ProtectionModeChanged", GAMEMODE, "default", nil)
+ mode = "default"
+ end
+end
diff --git a/lua/acf/shared/acf_userconfig_example.lua b/lua/acf/shared/acf_userconfig_example.lua
new file mode 100644
index 000000000..615d397c4
--- /dev/null
+++ b/lua/acf/shared/acf_userconfig_example.lua
@@ -0,0 +1,22 @@
+--[[
+
+ This file is loaded when ACF starts, just after all of the settings are set to their default values.
+ Rename this file to acf_userconfig.lua to enable this file, and customize those settings.
+
+ Move this file outside of the ACF folder to stop it being overwritten.
+ Put it in another addon folder (acf2, acfconfig), or put it in garrysmod/lua/acf/shared/
+
+]]--
+
+-- IMPORTANT: AddCSLuaFile is required! Do not remove it.
+AddCSLuaFile()
+
+
+
+-- Some example settings are below. They enable damage protection, double gun accuracy, and make shots more likely to be accurate.
+-- There are more settings like this. Find them all in lua/autorun/shared/acf_globals.lua
+
+
+ACF.EnableDefaultDP = true -- Enable the inbuilt damage protection system.
+ACF.GunInaccuracyScale = 0.5 -- Make guns 2x more accurate by halving the spread scale.
+ACF.GunInaccuracyBias = 1.2 -- Shots are more likely to be accurate with bias < 2
\ No newline at end of file
diff --git a/lua/acf/shared/acfcratelist.lua b/lua/acf/shared/acfcratelist.lua
new file mode 100644
index 000000000..da573cca5
--- /dev/null
+++ b/lua/acf/shared/acfcratelist.lua
@@ -0,0 +1,401 @@
+AddCSLuaFile( "acf/shared/acfcratelist.lua" )
+
+local AmmoTable = {} --Start ammo containers listing
+
+local AmmoSmall = {}
+ AmmoSmall.id = "AmmoSmall"
+ AmmoSmall.ent = "acf_ammo"
+ AmmoSmall.type = "Ammo"
+ AmmoSmall.name = "Small Ammo Crate"
+ AmmoSmall.desc = "Small ammo crate\n"
+ AmmoSmall.model = "models/ammocrate_small.mdl"
+ AmmoSmall.weight = 10
+ AmmoSmall.volume = 2198
+AmmoTable["AmmoSmall"] = AmmoSmall
+
+local AmmoMedCube = {}
+ AmmoMedCube.id = "AmmoMedCube"
+ AmmoMedCube.ent = "acf_ammo"
+ AmmoMedCube.type = "Ammo"
+ AmmoMedCube.name = "Medium cubic ammo crate"
+ AmmoMedCube.desc = "Medium cubic ammo crate\n"
+ AmmoMedCube.model = "models/ammocrate_medium_small.mdl"
+ AmmoMedCube.weight = 80
+ AmmoMedCube.volume = 17769
+AmmoTable["AmmoMedCube"] = AmmoMedCube
+
+local AmmoMedium = {}
+ AmmoMedium.id = "AmmoMedium"
+ AmmoMedium.ent = "acf_ammo"
+ AmmoMedium.type = "Ammo"
+ AmmoMedium.name = "Medium Ammo Crate"
+ AmmoMedium.desc = "Medium ammo crate\n"
+ AmmoMedium.model = "models/ammocrate_medium.mdl"
+ AmmoMedium.weight = 150
+ AmmoMedium.volume = 35105
+AmmoTable["AmmoMedium"] = AmmoMedium
+
+local AmmoLarge = {}
+ AmmoLarge.id = "AmmoLarge"
+ AmmoLarge.ent = "acf_ammo"
+ AmmoLarge.type = "Ammo"
+ AmmoLarge.name = "Large Ammo Crate"
+ AmmoLarge.desc = "Large ammo crate\n"
+ AmmoLarge.model = "models/ammocrate_large.mdl"
+ AmmoLarge.weight = 1000
+ AmmoLarge.volume = 140503
+AmmoTable["AmmoLarge"] = AmmoLarge
+
+local Ammo1x1x8 = {}
+ Ammo1x1x8.id = "Ammo1x1x8"
+ Ammo1x1x8.ent = "acf_ammo"
+ Ammo1x1x8.type = "Ammo"
+ Ammo1x1x8.name = "Modular Ammo Crate"
+ Ammo1x1x8.desc = "Modular Ammo Crate 1x1x8 Size\n"
+ Ammo1x1x8.model = "models/ammocrates/ammo_1x1x8.mdl"
+ Ammo1x1x8.weight = 40
+ Ammo1x1x8.volume = 10872
+AmmoTable["Ammo1x1x8"] = Ammo1x1x8
+
+local Ammo1x1x6 = {}
+ Ammo1x1x6.id = "Ammo1x1x6"
+ Ammo1x1x6.ent = "acf_ammo"
+ Ammo1x1x6.type = "Ammo"
+ Ammo1x1x6.name = "Modular Ammo Crate"
+ Ammo1x1x6.desc = "Modular Ammo Crate 1x1x6 Size\n"
+ Ammo1x1x6.model = "models/ammocrates/ammo_1x1x6.mdl"
+ Ammo1x1x6.weight = 30
+ Ammo1x1x6.volume = 8202
+AmmoTable["Ammo1x1x6"] = Ammo1x1x6
+
+local Ammo1x1x4 = {}
+ Ammo1x1x4.id = "Ammo1x1x4"
+ Ammo1x1x4.ent = "acf_ammo"
+ Ammo1x1x4.type = "Ammo"
+ Ammo1x1x4.name = "Modular Ammo Crate"
+ Ammo1x1x4.desc = "Modular Ammo Crate 1x1x4 Size\n"
+ Ammo1x1x4.model = "models/ammocrates/ammo_1x1x4.mdl"
+ Ammo1x1x4.weight = 20
+ Ammo1x1x4.volume = 5519
+AmmoTable["Ammo1x1x4"] = Ammo1x1x4
+
+local Ammo1x1x2 = {}
+ Ammo1x1x2.id = "Ammo1x1x2"
+ Ammo1x1x2.ent = "acf_ammo"
+ Ammo1x1x2.type = "Ammo"
+ Ammo1x1x2.name = "Modular Ammo Crate"
+ Ammo1x1x2.desc = "Modular Ammo Crate 1x1x2 Size\n"
+ Ammo1x1x2.model = "models/ammocrates/ammo_1x1x2.mdl"
+ Ammo1x1x2.weight = 10
+ Ammo1x1x2.volume = 2743
+AmmoTable["Ammo1x1x2"] = Ammo1x1x2
+
+local Ammo2x2x1 = {}
+ Ammo2x2x1.id = "Ammo2x2x1"
+ Ammo2x2x1.ent = "acf_ammo"
+ Ammo2x2x1.type = "Ammo"
+ Ammo2x2x1.name = "Modular Ammo Crate"
+ Ammo2x2x1.desc = "Modular Ammo Crate 2x2x1 Size\n"
+ Ammo2x2x1.model = "models/ammocrates/ammocrate_2x2x1.mdl"
+ Ammo2x2x1.weight = 20
+ Ammo2x2x1.volume = 3200
+AmmoTable["Ammo2x2x1"] = Ammo2x2x1
+
+local Ammo2x2x2 = {}
+ Ammo2x2x2.id = "Ammo2x2x2"
+ Ammo2x2x2.ent = "acf_ammo"
+ Ammo2x2x2.type = "Ammo"
+ Ammo2x2x2.name = "Modular Ammo Crate"
+ Ammo2x2x2.desc = "Modular Ammo Crate 2x2x2 Size\n"
+ Ammo2x2x2.model = "models/ammocrates/ammocrate_2x2x2.mdl"
+ Ammo2x2x2.weight = 40
+ Ammo2x2x2.volume = 8000
+AmmoTable["Ammo2x2x2"] = Ammo2x2x2
+
+local Ammo2x2x4 = {}
+ Ammo2x2x4.id = "Ammo2x2x4"
+ Ammo2x2x4.ent = "acf_ammo"
+ Ammo2x2x4.type = "Ammo"
+ Ammo2x2x4.name = "Modular Ammo Crate"
+ Ammo2x2x4.desc = "Modular Ammo Crate 2x2x4 Size\n"
+ Ammo2x2x4.model = "models/ammocrates/ammocrate_2x2x4.mdl"
+ Ammo2x2x4.weight = 80
+ Ammo2x2x4.volume = 18000
+AmmoTable["Ammo2x2x4"] = Ammo2x2x4
+
+local Ammo2x2x6 = {}
+ Ammo2x2x6.id = "Ammo2x2x6"
+ Ammo2x2x6.ent = "acf_ammo"
+ Ammo2x2x6.type = "Ammo"
+ Ammo2x2x6.name = "Modular Ammo Crate"
+ Ammo2x2x6.desc = "Modular Ammo Crate 2x2x6 Size\n"
+ Ammo2x2x6.model = "models/ammocrates/ammo_2x2x6.mdl"
+ Ammo2x2x6.weight = 120
+ Ammo2x2x6.volume = 33179
+AmmoTable["Ammo2x2x6"] = Ammo2x2x6
+
+local Ammo2x2x8 = {}
+ Ammo2x2x8.id = "Ammo2x2x8"
+ Ammo2x2x8.ent = "acf_ammo"
+ Ammo2x2x8.type = "Ammo"
+ Ammo2x2x8.name = "Modular Ammo Crate"
+ Ammo2x2x8.desc = "Modular Ammo Crate 2x2x8 Size\n"
+ Ammo2x2x8.model = "models/ammocrates/ammo_2x2x8.mdl"
+ Ammo2x2x8.weight = 160
+ Ammo2x2x8.volume = 45902
+AmmoTable["Ammo2x2x8"] = Ammo2x2x8
+
+local Ammo2x3x1 = {}
+ Ammo2x3x1.id = "Ammo2x3x1"
+ Ammo2x3x1.ent = "acf_ammo"
+ Ammo2x3x1.type = "Ammo"
+ Ammo2x3x1.name = "Modular Ammo Crate"
+ Ammo2x3x1.desc = "Modular Ammo Crate 2x3x1 Size\n"
+ Ammo2x3x1.model = "models/ammocrates/ammocrate_2x3x1.mdl"
+ Ammo2x3x1.weight = 30
+ Ammo2x3x1.volume = 5119
+AmmoTable["Ammo2x3x1"] = Ammo2x3x1
+
+local Ammo2x3x2 = {}
+ Ammo2x3x2.id = "Ammo2x3x2"
+ Ammo2x3x2.ent = "acf_ammo"
+ Ammo2x3x2.type = "Ammo"
+ Ammo2x3x2.name = "Modular Ammo Crate"
+ Ammo2x3x2.desc = "Modular Ammo Crate 2x3x2 Size\n"
+ Ammo2x3x2.model = "models/ammocrates/ammocrate_2x3x2.mdl"
+ Ammo2x3x2.weight = 60
+ Ammo2x3x2.volume = 12799
+AmmoTable["Ammo2x3x2"] = Ammo2x3x2
+
+local Ammo2x3x4 = {}
+ Ammo2x3x4.id = "Ammo2x3x4"
+ Ammo2x3x4.ent = "acf_ammo"
+ Ammo2x3x4.type = "Ammo"
+ Ammo2x3x4.name = "Modular Ammo Crate"
+ Ammo2x3x4.desc = "Modular Ammo Crate 2x3x4 Size\n"
+ Ammo2x3x4.model = "models/ammocrates/ammocrate_2x3x4.mdl"
+ Ammo2x3x4.weight = 120
+ Ammo2x3x4.volume = 28800
+AmmoTable["Ammo2x3x4"] = Ammo2x3x4
+
+local Ammo2x3x6 = {}
+ Ammo2x3x6.id = "Ammo2x3x6"
+ Ammo2x3x6.ent = "acf_ammo"
+ Ammo2x3x6.type = "Ammo"
+ Ammo2x3x6.name = "Modular Ammo Crate"
+ Ammo2x3x6.desc = "Modular Ammo Crate 2x3x6 Size\n"
+ Ammo2x3x6.model = "models/ammocrates/ammocrate_2x3x6.mdl"
+ Ammo2x3x6.weight = 180
+ Ammo2x3x6.volume = 43421
+AmmoTable["Ammo2x3x6"] = Ammo2x3x6
+
+local Ammo2x3x8 = {}
+ Ammo2x3x8.id = "Ammo2x3x8"
+ Ammo2x3x8.ent = "acf_ammo"
+ Ammo2x3x8.type = "Ammo"
+ Ammo2x3x8.name = "Modular Ammo Crate"
+ Ammo2x3x8.desc = "Modular Ammo Crate 2x3x8 Size\n"
+ Ammo2x3x8.model = "models/ammocrates/ammocrate_2x3x8.mdl"
+ Ammo2x3x8.weight = 240
+ Ammo2x3x8.volume = 57509
+AmmoTable["Ammo2x3x8"] = Ammo2x3x8
+
+local Ammo2x4x1 = {}
+ Ammo2x4x1.id = "Ammo2x4x1"
+ Ammo2x4x1.ent = "acf_ammo"
+ Ammo2x4x1.type = "Ammo"
+ Ammo2x4x1.name = "Modular Ammo Crate"
+ Ammo2x4x1.desc = "Modular Ammo Crate 2x4x1 Size\n"
+ Ammo2x4x1.model = "models/ammocrates/ammocrate_2x4x1.mdl"
+ Ammo2x4x1.weight = 40
+ Ammo2x4x1.volume = 7200
+AmmoTable["Ammo2x4x1"] = Ammo2x4x1
+
+local Ammo2x4x2 = {}
+ Ammo2x4x2.id = "Ammo2x4x2"
+ Ammo2x4x2.ent = "acf_ammo"
+ Ammo2x4x2.type = "Ammo"
+ Ammo2x4x2.name = "Modular Ammo Crate"
+ Ammo2x4x2.desc = "Modular Ammo Crate 2x4x2 Size\n"
+ Ammo2x4x2.model = "models/ammocrates/ammocrate_2x4x2.mdl"
+ Ammo2x4x2.weight = 80
+ Ammo2x4x2.volume = 18000
+AmmoTable["Ammo2x4x2"] = Ammo2x4x2
+
+local Ammo2x4x4 = {}
+ Ammo2x4x4.id = "Ammo2x4x4"
+ Ammo2x4x4.ent = "acf_ammo"
+ Ammo2x4x4.type = "Ammo"
+ Ammo2x4x4.name = "Modular Ammo Crate"
+ Ammo2x4x4.desc = "Modular Ammo Crate 2x4x4 Size\n"
+ Ammo2x4x4.model = "models/ammocrates/ammocrate_2x4x4.mdl"
+ Ammo2x4x4.weight = 160
+ Ammo2x4x4.volume = 40500
+AmmoTable["Ammo2x4x4"] = Ammo2x4x4
+
+local Ammo2x4x6 = {}
+ Ammo2x4x6.id = "Ammo2x4x6"
+ Ammo2x4x6.ent = "acf_ammo"
+ Ammo2x4x6.type = "Ammo"
+ Ammo2x4x6.name = "Modular Ammo Crate"
+ Ammo2x4x6.desc = "Modular Ammo Crate 2x4x6 Size\n"
+ Ammo2x4x6.model = "models/ammocrates/ammocrate_2x4x6.mdl"
+ Ammo2x4x6.weight = 240
+ Ammo2x4x6.volume = 61200
+AmmoTable["Ammo2x4x6"] = Ammo2x4x6
+
+local Ammo2x4x8 = {}
+ Ammo2x4x8.id = "Ammo2x4x8"
+ Ammo2x4x8.ent = "acf_ammo"
+ Ammo2x4x8.type = "Ammo"
+ Ammo2x4x8.name = "Modular Ammo Crate"
+ Ammo2x4x8.desc = "Modular Ammo Crate 2x4x8 Size\n"
+ Ammo2x4x8.model = "models/ammocrates/ammocrate_2x4x8.mdl"
+ Ammo2x4x8.weight = 320
+ Ammo2x4x8.volume = 80999
+AmmoTable["Ammo2x4x8"] = Ammo2x4x8
+
+local Ammo3x4x1 = {}
+ Ammo3x4x1.id = "Ammo3x4x1"
+ Ammo3x4x1.ent = "acf_ammo"
+ Ammo3x4x1.type = "Ammo"
+ Ammo3x4x1.name = "Modular Ammo Crate"
+ Ammo3x4x1.desc = "Modular Ammo Crate 3x4x1 Size\n"
+ Ammo3x4x1.model = "models/ammocrates/ammocrate_3x4x1.mdl"
+ Ammo3x4x1.weight = 60
+ Ammo3x4x1.volume = 11520
+AmmoTable["Ammo3x4x1"] = Ammo3x4x1
+
+local Ammo3x4x2 = {}
+ Ammo3x4x2.id = "Ammo3x4x2"
+ Ammo3x4x2.ent = "acf_ammo"
+ Ammo3x4x2.type = "Ammo"
+ Ammo3x4x2.name = "Modular Ammo Crate"
+ Ammo3x4x2.desc = "Modular Ammo Crate 3x4x2 Size\n"
+ Ammo3x4x2.model = "models/ammocrates/ammocrate_3x4x2.mdl"
+ Ammo3x4x2.weight = 120
+ Ammo3x4x2.volume = 28800
+AmmoTable["Ammo3x4x2"] = Ammo3x4x2
+
+local Ammo3x4x4 = {}
+ Ammo3x4x4.id = "Ammo3x4x4"
+ Ammo3x4x4.ent = "acf_ammo"
+ Ammo3x4x4.type = "Ammo"
+ Ammo3x4x4.name = "Modular Ammo Crate"
+ Ammo3x4x4.desc = "Modular Ammo Crate 3x4x4 Size\n"
+ Ammo3x4x4.model = "models/ammocrates/ammocrate_3x4x4.mdl"
+ Ammo3x4x4.weight = 240
+ Ammo3x4x4.volume = 64800
+AmmoTable["Ammo3x4x4"] = Ammo3x4x4
+
+local Ammo3x4x6 = {}
+ Ammo3x4x6.id = "Ammo3x4x6"
+ Ammo3x4x6.ent = "acf_ammo"
+ Ammo3x4x6.type = "Ammo"
+ Ammo3x4x6.name = "Modular Ammo Crate"
+ Ammo3x4x6.desc = "Modular Ammo Crate 3x4x6 Size\n"
+ Ammo3x4x6.model = "models/ammocrates/ammocrate_3x4x6.mdl"
+ Ammo3x4x6.weight = 360
+ Ammo3x4x6.volume = 97920
+AmmoTable["Ammo3x4x6"] = Ammo3x4x6
+
+local Ammo3x4x8 = {}
+ Ammo3x4x8.id = "Ammo3x4x8"
+ Ammo3x4x8.ent = "acf_ammo"
+ Ammo3x4x8.type = "Ammo"
+ Ammo3x4x8.name = "Modular Ammo Crate"
+ Ammo3x4x8.desc = "Modular Ammo Crate 3x4x8 Size\n"
+ Ammo3x4x8.model = "models/ammocrates/ammocrate_3x4x8.mdl"
+ Ammo3x4x8.weight = 480
+ Ammo3x4x8.volume = 129599
+AmmoTable["Ammo3x4x8"] = Ammo3x4x8
+
+local Ammo4x4x1 = {}
+ Ammo4x4x1.id = "Ammo4x4x1"
+ Ammo4x4x1.ent = "acf_ammo"
+ Ammo4x4x1.type = "Ammo"
+ Ammo4x4x1.name = "Modular Ammo Crate"
+ Ammo4x4x1.desc = "Modular Ammo Crate 4x4x1 Size\n"
+ Ammo4x4x1.model = "models/ammocrates/ammo_4x4x1.mdl"
+ Ammo4x4x1.weight = 80
+ Ammo4x4x1.volume = 23186
+AmmoTable["Ammo4x4x1"] = Ammo4x4x1
+
+local Ammo4x4x2 = {}
+ Ammo4x4x2.id = "Ammo4x4x2"
+ Ammo4x4x2.ent = "acf_ammo"
+ Ammo4x4x2.type = "Ammo"
+ Ammo4x4x2.name = "Modular Ammo Crate"
+ Ammo4x4x2.desc = "Modular Ammo Crate 4x4x2 Size\n"
+ Ammo4x4x2.model = "models/ammocrates/ammocrate_4x4x2.mdl"
+ Ammo4x4x2.weight = 160
+ Ammo4x4x2.volume = 40500
+AmmoTable["Ammo4x4x2"] = Ammo4x4x2
+
+local Ammo4x4x4 = {}
+ Ammo4x4x4.id = "Ammo4x4x4"
+ Ammo4x4x4.ent = "acf_ammo"
+ Ammo4x4x4.type = "Ammo"
+ Ammo4x4x4.name = "Modular Ammo Crate"
+ Ammo4x4x4.desc = "Modular Ammo Crate 4x4x4 Size\n"
+ Ammo4x4x4.model = "models/ammocrates/ammocrate_4x4x4.mdl"
+ Ammo4x4x4.weight = 320
+ Ammo4x4x4.volume = 91125
+AmmoTable["Ammo4x4x4"] = Ammo4x4x4
+
+local Ammo4x4x6 = {}
+ Ammo4x4x6.id = "Ammo4x4x6"
+ Ammo4x4x6.ent = "acf_ammo"
+ Ammo4x4x6.type = "Ammo"
+ Ammo4x4x6.name = "Modular Ammo Crate"
+ Ammo4x4x6.desc = "Modular Ammo Crate 4x4x6 Size\n"
+ Ammo4x4x6.model = "models/ammocrates/ammocrate_4x4x6.mdl"
+ Ammo4x4x6.weight = 480
+ Ammo4x4x6.volume = 137700
+AmmoTable["Ammo4x4x6"] = Ammo4x4x6
+
+local Ammo4x4x8 = {}
+ Ammo4x4x8.id = "Ammo4x4x8"
+ Ammo4x4x8.ent = "acf_ammo"
+ Ammo4x4x8.type = "Ammo"
+ Ammo4x4x8.name = "Modular Ammo Crate"
+ Ammo4x4x8.desc = "Modular Ammo Crate 4x4x8 Size\n"
+ Ammo4x4x8.model = "models/ammocrates/ammocrate_4x4x8.mdl"
+ Ammo4x4x8.weight = 640
+ Ammo4x4x8.volume = 182249
+AmmoTable["Ammo4x4x8"] = Ammo4x4x8
+
+local Ammo4x6x8 = {}
+ Ammo4x6x8.id = "Ammo4x6x8"
+ Ammo4x6x8.ent = "acf_ammo"
+ Ammo4x6x8.type = "Ammo"
+ Ammo4x6x8.name = "Modular Ammo Crate"
+ Ammo4x6x8.desc = "Modular Ammo Crate 4x6x8 Size\n"
+ Ammo4x6x8.model = "models/ammocrates/ammo_4x6x8.mdl"
+ Ammo4x6x8.weight = 800
+ Ammo4x6x8.volume = 272664
+AmmoTable["Ammo4x6x8"] = Ammo4x6x8
+
+local Ammo4x6x6 = {}
+ Ammo4x6x6.id = "Ammo4x6x6"
+ Ammo4x6x6.ent = "acf_ammo"
+ Ammo4x6x6.type = "Ammo"
+ Ammo4x6x6.name = "Modular Ammo Crate"
+ Ammo4x6x6.desc = "Modular Ammo Crate 4x6x6 Size\n"
+ Ammo4x6x6.model = "models/ammocrates/ammo_4x6x6.mdl"
+ Ammo4x6x6.weight = 720
+ Ammo4x6x6.volume = 204106
+AmmoTable["Ammo4x6x6"] = Ammo4x6x6
+
+local Ammo4x8x8 = {}
+ Ammo4x8x8.id = "Ammo4x8x8"
+ Ammo4x8x8.ent = "acf_ammo"
+ Ammo4x8x8.type = "Ammo"
+ Ammo4x8x8.name = "Modular Ammo Crate"
+ Ammo4x8x8.desc = "Modular Ammo Crate 4x8x8 Size\n"
+ Ammo4x8x8.model = "models/ammocrates/ammo_4x8x8.mdl"
+ Ammo4x8x8.weight = 960
+ Ammo4x8x8.volume = 366397
+AmmoTable["Ammo4x8x8"] = Ammo4x8x8
+
+list.Set( "ACFEnts", "Ammo", AmmoTable ) --end ammo containers listing
diff --git a/lua/acf/shared/acfloader.lua b/lua/acf/shared/acfloader.lua
new file mode 100644
index 000000000..d358a28c3
--- /dev/null
+++ b/lua/acf/shared/acfloader.lua
@@ -0,0 +1,112 @@
+
+-- This loads the files in the engine, gearbox, fuel, and gun folders!
+-- Go edit those files instead of this one.
+
+AddCSLuaFile()
+
+local GunClasses = {}
+local GunTable = {}
+local MobilityTable = {}
+local FuelTankTable = {}
+
+-- setup base classes
+local gun_base = {
+ ent = "acf_gun",
+ type = "Guns"
+}
+
+local engine_base = {
+ ent = "acf_engine",
+ type = "Mobility"
+}
+
+local gearbox_base = {
+ ent = "acf_gearbox",
+ type = "Mobility",
+ sound = "vehicles/junker/jnk_fourth_cruise_loop2.wav"
+}
+
+local fueltank_base = {
+ ent = "acf_fueltank",
+ type = "Mobility"
+}
+
+-- add gui stuff to base classes if this is client
+if CLIENT then
+ gun_base.guicreate = function( Panel, Table ) ACFGunGUICreate( Table ) end or nil
+ gun_base.guiupdate = function() return end
+ engine_base.guicreate = function( panel, tbl ) ACFEngineGUICreate( tbl ) end or nil
+ engine_base.guiupdate = function() return end
+ gearbox_base.guicreate = function( panel, tbl ) ACFGearboxGUICreate( tbl ) end or nil
+ gearbox_base.guiupdate = function() return end
+ fueltank_base.guicreate = function( panel, tbl ) ACFFuelTankGUICreate( tbl ) end or nil
+ fueltank_base.guiupdate = function( panel, tbl ) ACFFuelTankGUIUpdate( tbl ) end or nil
+end
+
+-- some factory functions for defining ents
+function ACF_defineGunClass( id, data )
+ data.id = id
+ GunClasses[ id ] = data
+end
+
+function ACF_defineGun( id, data )
+ data.id = id
+ data.round.id = id
+ table.Inherit( data, gun_base )
+ GunTable[ id ] = data
+end
+
+function ACF_DefineEngine( id, data )
+ data.id = id
+ table.Inherit( data, engine_base )
+ MobilityTable[ id ] = data
+end
+
+function ACF_DefineGearbox( id, data )
+ data.id = id
+ table.Inherit( data, gearbox_base )
+ MobilityTable[ id ] = data
+end
+
+function ACF_DefineFuelTank( id, data )
+ data.id = id
+ table.Inherit( data, fueltank_base )
+ MobilityTable[ id ] = data
+end
+
+function ACF_DefineFuelTankSize( id, data )
+ data.id = id
+ table.Inherit( data, fueltank_base )
+ FuelTankTable[ id ] = data
+end
+
+-- search for and load a bunch of files or whatever
+local guns = file.Find( "acf/shared/guns/*.lua", "LUA" )
+for k, v in pairs( guns ) do
+ AddCSLuaFile( "acf/shared/guns/" .. v )
+ include( "acf/shared/guns/" .. v )
+end
+
+local engines = file.Find( "acf/shared/engines/*.lua", "LUA" )
+for k, v in pairs( engines ) do
+ AddCSLuaFile( "acf/shared/engines/" .. v )
+ include( "acf/shared/engines/" .. v )
+end
+
+local gearboxes = file.Find( "acf/shared/gearboxes/*.lua", "LUA" )
+for k, v in pairs( gearboxes ) do
+ AddCSLuaFile( "acf/shared/gearboxes/" .. v )
+ include( "acf/shared/gearboxes/" .. v )
+end
+
+local fueltanks = file.Find( "acf/shared/fueltanks/*.lua", "LUA" )
+for k, v in pairs( fueltanks ) do
+ AddCSLuaFile( "acf/shared/fueltanks/" .. v )
+ include( "acf/shared/fueltanks/" .. v )
+end
+
+-- now that the tables are populated, throw them in the acf ents list
+list.Set( "ACFClasses", "GunClass", GunClasses )
+list.Set( "ACFEnts", "Guns", GunTable )
+list.Set( "ACFEnts", "Mobility", MobilityTable )
+list.Set( "ACFEnts", "FuelTanks", FuelTankTable )
diff --git a/lua/ACF/Shared/ACFMissileList.lua b/lua/acf/shared/acfmissilelist.lua
similarity index 100%
rename from lua/ACF/Shared/ACFMissileList.lua
rename to lua/acf/shared/acfmissilelist.lua
diff --git a/lua/acf/shared/engines/b4.lua b/lua/acf/shared/engines/b4.lua
new file mode 100644
index 000000000..e9ac94fab
--- /dev/null
+++ b/lua/acf/shared/engines/b4.lua
@@ -0,0 +1,70 @@
+
+-- Flat 4 engines
+
+ACF_DefineEngine( "1.4-B4", {
+ name = "1.4L Flat 4 Petrol",
+ desc = "Small air cooled flat four, most commonly found in nazi insects",
+ model = "models/engines/b4small.mdl",
+ sound = "acf_engines/b4_petrolsmall.wav",
+ category = "B4",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 60,
+ torque = 105,
+ flywheelmass = 0.06,
+ idlerpm = 600,
+ peakminrpm = 2600,
+ peakmaxrpm = 4200,
+ limitrpm = 4500
+} )
+
+ACF_DefineEngine( "2.1-B4", {
+ name = "2.1L Flat 4 Petrol",
+ desc = "Tuned up flat four, probably find this in things that go fast in a desert.",
+ model = "models/engines/b4small.mdl",
+ sound = "acf_engines/b4_petrolmedium.wav",
+ category = "B4",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 125,
+ torque = 180,
+ flywheelmass = 0.15,
+ idlerpm = 700,
+ peakminrpm = 3000,
+ peakmaxrpm = 4800,
+ limitrpm = 5000
+} )
+
+ACF_DefineEngine( "3.2-B4", {
+ name = "3.2L Flat 4 Petrol",
+ desc = "Bored out fuckswindleton batshit flat four. Fuck yourself.",
+ model = "models/engines/b4med.mdl",
+ sound = "acf_engines/b4_petrollarge.wav",
+ category = "B4",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 210,
+ torque = 252,
+ flywheelmass = 0.15,
+ idlerpm = 900,
+ peakminrpm = 3400,
+ peakmaxrpm = 5500,
+ limitrpm = 6500
+} )
+
+ACF_DefineEngine( "2.4-B4", {
+ name = "2.4L Flat 4 Multifuel",
+ desc = "Tiny military-grade multifuel. Heavy, but grunts hard.",
+ model = "models/engines/b4small.mdl",
+ sound = "acf_extra/vehiclefx/engines/coh/ba11.wav",
+ category = "B4",
+ fuel = "Multifuel",
+ enginetype = "GenericDiesel",
+ weight = 135,
+ torque = 248,
+ flywheelmass = 0.4,
+ idlerpm = 550,
+ peakminrpm = 1250,
+ peakmaxrpm = 2650,
+ limitrpm = 2800
+} )
diff --git a/lua/acf/shared/engines/b6.lua b/lua/acf/shared/engines/b6.lua
new file mode 100644
index 000000000..c8deae89c
--- /dev/null
+++ b/lua/acf/shared/engines/b6.lua
@@ -0,0 +1,71 @@
+
+-- Flat 6 engines
+
+ACF_DefineEngine( "2.8-B6", {
+ name = "2.8L Flat 6 Petrol",
+ desc = "Car sized flat six engine, sporty and light",
+ model = "models/engines/b6small.mdl",
+ sound = "acf_engines/b6_petrolsmall.wav",
+ category = "B6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 100,
+ torque = 136,
+ flywheelmass = 0.08,
+ idlerpm = 750,
+ peakminrpm = 4300,
+ peakmaxrpm = 6950,
+ limitrpm = 7250
+} )
+
+ACF_DefineEngine( "5.0-B6", {
+ name = "5.0L Flat 6 Petrol",
+ desc = "Sports car grade flat six, renown for their smooth operation and light weight",
+ model = "models/engines/b6med.mdl",
+ sound = "acf_engines/b6_petrolmedium.wav",
+ category = "B6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 240,
+ torque = 330,
+ flywheelmass = 0.11,
+ idlerpm = 900,
+ peakminrpm = 3500,
+ peakmaxrpm = 6000,
+ limitrpm = 6800
+} )
+
+ACF_DefineEngine( "8.3-B6", {
+ name = "8.3L Flat 6 Multifuel",
+ desc = "Military-grade multifuel boxer engine. Although heavy, it is compact, durable, and has excellent performance under adverse conditions.",
+ model = "models/engines/b6med.mdl",
+ sound = "acf_engines/v8_diesel.wav",
+ category = "B6",
+ fuel = "Multifuel",
+ enginetype = "GenericDiesel",
+ weight = 480,
+ torque = 565,
+ flywheelmass = 0.65,
+ idlerpm = 500,
+ peakminrpm = 1900,
+ peakmaxrpm = 3600,
+ limitrpm = 4200
+} )
+
+
+ACF_DefineEngine( "15.8-B6", {
+ name = "15.8L Flat 6 Petrol",
+ desc = "Monstrous aircraft-grade boxer with a high rev range biased powerband",
+ model = "models/engines/b6large.mdl",
+ sound = "acf_engines/b6_petrollarge.wav",
+ category = "B6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 725,
+ torque = 1100,
+ flywheelmass = 1,
+ idlerpm = 620,
+ peakminrpm = 2500,
+ peakmaxrpm = 4275,
+ limitrpm = 4900
+} )
diff --git a/lua/acf/shared/engines/electric.lua b/lua/acf/shared/engines/electric.lua
new file mode 100644
index 000000000..39d0eed6b
--- /dev/null
+++ b/lua/acf/shared/engines/electric.lua
@@ -0,0 +1,139 @@
+
+-- Electric motors
+
+ACF_DefineEngine( "Electric-Small", {
+ name = "Electric motor, Small",
+ desc = "A small electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy",
+ model = "models/engines/emotorsmall.mdl",
+ sound = "acf_engines/electric_small.wav",
+ category = "Electric",
+ fuel = "Electric",
+ enginetype = "Electric",
+ weight = 250,
+ torque = 384,
+ flywheelmass = 0.3,
+ idlerpm = 10,
+ peakminrpm = 1,
+ peakmaxrpm = 1,
+ limitrpm = 10000,
+ iselec = true,
+ flywheeloverride = 5000
+} )
+
+ACF_DefineEngine( "Electric-Medium", {
+ name = "Electric motor, Medium",
+ desc = "A medium electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy",
+ model = "models/engines/emotormed.mdl",
+ sound = "acf_engines/electric_medium.wav",
+ category = "Electric",
+ fuel = "Electric",
+ enginetype = "Electric",
+ weight = 850,
+ torque = 1152,
+ flywheelmass = 1.5,
+ idlerpm = 10,
+ peakminrpm = 1,
+ peakmaxrpm = 1,
+ limitrpm = 7000,
+ iselec = true,
+ flywheeloverride = 8000
+} )
+
+ACF_DefineEngine( "Electric-Large", {
+ name = "Electric motor, Large",
+ desc = "A huge electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy",
+ model = "models/engines/emotorlarge.mdl",
+ sound = "acf_engines/electric_large.wav",
+ category = "Electric",
+ fuel = "Electric",
+ enginetype = "Electric",
+ weight = 1900,
+ torque = 3360,
+ flywheelmass = 11.2,
+ idlerpm = 10,
+ peakminrpm = 1,
+ peakmaxrpm = 1,
+ limitrpm = 4500,
+ iselec = true,
+ flywheeloverride = 6000
+} )
+
+ACF_DefineEngine( "Electric-Tiny-NoBatt", {
+ name = "Electric motor, Tiny, Standalone",
+ desc = "A pint-size electric motor, for the lightest of light utility work. Can power electric razors, desk fans, or your hopes and dreams\n\nElectric motors provide huge amounts of torque, but are very heavy.\n\nStandalone electric motors don't have integrated batteries, saving on weight and volume, but require you to supply your own batteries.",
+ model = "models/engines/emotor-standalone-tiny.mdl",
+ sound = "acf_engines/electric_small.wav",
+ category = "Electric",
+ fuel = "Electric",
+ enginetype = "Electric",
+ requiresfuel = true,
+ weight = 50, --250
+ torque = 40,
+ flywheelmass = 0.025,
+ idlerpm = 10,
+ peakminrpm = 1,
+ peakmaxrpm = 1,
+ limitrpm = 10000,
+ iselec = true,
+ flywheeloverride = 500
+} )
+
+ACF_DefineEngine( "Electric-Small-NoBatt", {
+ name = "Electric motor, Small, Standalone",
+ desc = "A small electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy.\n\nStandalone electric motors don't have integrated batteries, saving on weight and volume, but require you to supply your own batteries.",
+ model = "models/engines/emotor-standalone-sml.mdl",
+ sound = "acf_engines/electric_small.wav",
+ category = "Electric",
+ fuel = "Electric",
+ enginetype = "Electric",
+ requiresfuel = true,
+ weight = 125, --250
+ torque = 384,
+ flywheelmass = 0.3,
+ idlerpm = 10,
+ peakminrpm = 1,
+ peakmaxrpm = 1,
+ limitrpm = 10000,
+ iselec = true,
+ flywheeloverride = 5000
+} )
+
+ACF_DefineEngine( "Electric-Medium-NoBatt", {
+ name = "Electric motor, Medium, Standalone",
+ desc = "A medium electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy.\n\nStandalone electric motors don't have integrated batteries, saving on weight and volume, but require you to supply your own batteries.",
+ model = "models/engines/emotor-standalone-mid.mdl",
+ sound = "acf_engines/electric_medium.wav",
+ category = "Electric",
+ fuel = "Electric",
+ enginetype = "Electric",
+ requiresfuel = true,
+ weight = 575, --800
+ torque = 1152,
+ flywheelmass = 1.5,
+ idlerpm = 10,
+ peakminrpm = 1,
+ peakmaxrpm = 1,
+ limitrpm = 7000,
+ iselec = true,
+ flywheeloverride = 8000
+} )
+
+ACF_DefineEngine( "Electric-Large-NoBatt", {
+ name = "Electric motor, Large, Standalone",
+ desc = "A huge electric motor, loads of torque, but low power\n\nElectric motors provide huge amounts of torque, but are very heavy.\n\nStandalone electric motors don't have integrated batteries, saving on weight and volume, but require you to supply your own batteries.",
+ model = "models/engines/emotor-standalone-big.mdl",
+ sound = "acf_engines/electric_large.wav",
+ category = "Electric",
+ fuel = "Electric",
+ enginetype = "Electric",
+ requiresfuel = true,
+ weight = 1500, --1900
+ torque = 3360,
+ flywheelmass = 11.2,
+ idlerpm = 10,
+ peakminrpm = 1,
+ peakmaxrpm = 1,
+ limitrpm = 4500,
+ iselec = true,
+ flywheeloverride = 6000
+} )
diff --git a/lua/acf/shared/engines/i2.lua b/lua/acf/shared/engines/i2.lua
new file mode 100644
index 000000000..c7d8752ff
--- /dev/null
+++ b/lua/acf/shared/engines/i2.lua
@@ -0,0 +1,38 @@
+
+-- Inline 2 engines
+
+ACF_DefineEngine( "0.8L-I2", {
+ name = "0.8L I2 Diesel",
+ desc = "For when a 3 banger is still too bulky for your micro-needs",
+ model = "models/engines/inline2s.mdl",
+ sound = "acf_engines/i4_diesel2.wav",
+ category = "I2",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 45,
+ torque = 105,
+ flywheelmass = 0.12,
+ idlerpm = 500,
+ peakminrpm = 750,
+ peakmaxrpm = 2450,
+ limitrpm = 2950
+} )
+
+
+
+ACF_DefineEngine( "10.0-I2", {
+ name = "10.0L I2 Diesel",
+ desc = "TORQUE.",
+ model = "models/engines/inline2b.mdl",
+ sound = "acf_engines/vtwin_large.wav",
+ category = "I2",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 800,
+ torque = 2000,
+ flywheelmass = 7,
+ idlerpm = 350,
+ peakminrpm = 450,
+ peakmaxrpm = 900,
+ limitrpm = 1200
+} )
diff --git a/lua/acf/shared/engines/i3.lua b/lua/acf/shared/engines/i3.lua
new file mode 100644
index 000000000..dadc32c77
--- /dev/null
+++ b/lua/acf/shared/engines/i3.lua
@@ -0,0 +1,108 @@
+
+-- Inline 3 engines
+
+-- Petrol
+
+ACF_DefineEngine( "1.2-I3", {
+ name = "1.2L I3 Petrol",
+ desc = "Tiny microcar engine, efficient but weak",
+ model = "models/engines/inline3s.mdl",
+ sound = "acf_engines/i4_petrolsmall2.wav",
+ category = "I3",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 40,
+ torque = 95,
+ flywheelmass = 0.05,
+ idlerpm = 1100,
+ peakminrpm = 3300,
+ peakmaxrpm = 5400,
+ limitrpm = 6000
+} )
+
+ACF_DefineEngine( "3.4-I3", {
+ name = "3.4L I3 Petrol",
+ desc = "Short block engine for light utility use",
+ model = "models/engines/inline3m.mdl",
+ sound = "acf_engines/i4_petrolmedium2.wav",
+ category = "I3",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 170,
+ torque = 195,
+ flywheelmass = 0.2,
+ idlerpm = 900,
+ peakminrpm = 3500,
+ peakmaxrpm = 6600,
+ limitrpm = 6800
+} )
+
+ACF_DefineEngine( "13.5-I3", {
+ name = "13.5L I3 Petrol",
+ desc = "Short block light tank engine, likes sideways mountings",
+ model = "models/engines/inline3b.mdl",
+ sound = "acf_engines/i4_petrollarge.wav",
+ category = "I3",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 500,
+ torque = 715,
+ flywheelmass = 3.7,
+ idlerpm = 500,
+ peakminrpm = 1900,
+ peakmaxrpm = 3500,
+ limitrpm = 3900
+} )
+
+-- Diesel
+
+ACF_DefineEngine( "1.1-I3", {
+ name = "1.1L I3 Diesel",
+ desc = "ATV grade 3-banger, enormous rev band but a choppy idle, great for light utility work",
+ model = "models/engines/inline3s.mdl",
+ sound = "acf_engines/i4_diesel2.wav",
+ category = "I3",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 65,
+ torque = 150,
+ flywheelmass = 0.2,
+ idlerpm = 550,
+ peakminrpm = 800,
+ peakmaxrpm = 2500,
+ limitrpm = 3000
+} )
+
+ACF_DefineEngine( "2.8-I3", {
+ name = "2.8L I3 Diesel",
+ desc = "Medium utility grade I3 diesel, for tractors",
+ model = "models/engines/inline3m.mdl",
+ sound = "acf_engines/i4_dieselmedium.wav",
+ category = "I3",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 200,
+ torque = 290,
+ flywheelmass = 1,
+ idlerpm = 600,
+ peakminrpm = 1200,
+ peakmaxrpm = 3600,
+ limitrpm = 3800
+} )
+
+ACF_DefineEngine( "11.0-I3", {
+ name = "11.0L I3 Diesel",
+ desc = "Light tank duty engine, compact yet grunts hard",
+ model = "models/engines/inline3b.mdl",
+ sound = "acf_engines/i4_diesellarge.wav",
+ category = "I3",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 650,
+ torque = 1200,
+ flywheelmass = 5,
+ idlerpm = 550,
+ peakminrpm = 650,
+ peakmaxrpm = 1800,
+ limitrpm = 2000
+} )
diff --git a/lua/acf/shared/engines/i4.lua b/lua/acf/shared/engines/i4.lua
new file mode 100644
index 000000000..f28ae2909
--- /dev/null
+++ b/lua/acf/shared/engines/i4.lua
@@ -0,0 +1,108 @@
+
+-- Inline 4 engines
+
+-- Petrol
+
+ACF_DefineEngine( "1.5-I4", {
+ name = "1.5L I4 Petrol",
+ desc = "Small car engine, not a whole lot of git",
+ model = "models/engines/inline4s.mdl",
+ sound = "acf_engines/i4_petrolsmall2.wav",
+ category = "I4",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 50,
+ torque = 90,
+ flywheelmass = 0.06,
+ idlerpm = 900,
+ peakminrpm = 4000,
+ peakmaxrpm = 6500,
+ limitrpm = 7500
+} )
+
+ACF_DefineEngine( "3.7-I4", {
+ name = "3.7L I4 Petrol",
+ desc = "Large inline 4, sees most use in light trucks",
+ model = "models/engines/inline4m.mdl",
+ sound = "acf_engines/i4_petrolmedium2.wav",
+ category = "I4",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 200,
+ torque = 240,
+ flywheelmass = 0.2,
+ idlerpm = 900,
+ peakminrpm = 3700,
+ peakmaxrpm = 6000,
+ limitrpm = 6500
+} )
+
+ACF_DefineEngine( "16.0-I4", {
+ name = "16.0L I4 Petrol",
+ desc = "Giant, thirsty I4 petrol, most commonly used in boats",
+ model = "models/engines/inline4l.mdl",
+ sound = "acf_engines/i4_petrollarge.wav",
+ category = "I4",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 600,
+ torque = 850,
+ flywheelmass = 4,
+ idlerpm = 500,
+ peakminrpm = 1750,
+ peakmaxrpm = 3250,
+ limitrpm = 3500
+} )
+
+-- Diesel
+
+ACF_DefineEngine( "1.6-I4", {
+ name = "1.6L I4 Diesel",
+ desc = "Small and light diesel, for low power applications requiring a wide powerband",
+ model = "models/engines/inline4s.mdl",
+ sound = "acf_engines/i4_diesel2.wav",
+ category = "I4",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 90,
+ torque = 150,
+ flywheelmass = 0.2,
+ idlerpm = 650,
+ peakminrpm = 1000,
+ peakmaxrpm = 3000,
+ limitrpm = 5000
+} )
+
+ACF_DefineEngine( "3.1-I4", {
+ name = "3.1L I4 Diesel",
+ desc = "Light truck duty diesel, good overall grunt",
+ model = "models/engines/inline4m.mdl",
+ sound = "acf_engines/i4_dieselmedium.wav",
+ category = "I4",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 250,
+ torque = 320,
+ flywheelmass = 1,
+ idlerpm = 500,
+ peakminrpm = 1150,
+ peakmaxrpm = 3500,
+ limitrpm = 4000
+} )
+
+ACF_DefineEngine( "15.0-I4", {
+ name = "15.0L I4 Diesel",
+ desc = "Small boat sized diesel, with large amounts of torque",
+ model = "models/engines/inline4l.mdl",
+ sound = "acf_engines/i4_diesellarge.wav",
+ category = "I4",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 800,
+ torque = 1400,
+ flywheelmass = 5,
+ idlerpm = 450,
+ peakminrpm = 500,
+ peakmaxrpm = 1800,
+ limitrpm = 2100
+} )
diff --git a/lua/acf/shared/engines/i5.lua b/lua/acf/shared/engines/i5.lua
new file mode 100644
index 000000000..0144db150
--- /dev/null
+++ b/lua/acf/shared/engines/i5.lua
@@ -0,0 +1,74 @@
+
+-- Inline 5 engines
+
+-- Petrol
+
+ACF_DefineEngine( "2.3-I5", {
+ name = "2.3L I5 Petrol",
+ desc = "Sedan-grade 5-cylinder, solid and dependable",
+ model = "models/engines/inline5s.mdl",
+ sound = "acf_engines/i5_petrolsmall.wav",
+ category = "I5",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 100,
+ torque = 125,
+ flywheelmass = 0.12,
+ idlerpm = 900,
+ peakminrpm = 3600,
+ peakmaxrpm = 5900,
+ limitrpm = 7000
+} )
+
+ACF_DefineEngine( "3.9-I5", {
+ name = "3.9L I5 Petrol",
+ desc = "Truck sized inline 5, strong with a good balance of revs and torques",
+ model = "models/engines/inline5m.mdl",
+ sound = "acf_engines/i5_petrolmedium.wav",
+ category = "I5",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 250,
+ torque = 275,
+ flywheelmass = 0.25,
+ idlerpm = 700,
+ peakminrpm = 3700,
+ peakmaxrpm = 6000,
+ limitrpm = 6500
+} )
+
+-- Diesel
+
+ACF_DefineEngine( "2.9-I5", {
+ name = "2.9L I5 Diesel",
+ desc = "Aging fuel-injected diesel, low in horsepower but very forgiving and durable",
+ model = "models/engines/inline5s.mdl",
+ sound = "acf_engines/i5_dieselsmall2.wav",
+ category = "I5",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 130,
+ torque = 180,
+ flywheelmass = 0.5,
+ idlerpm = 500,
+ peakminrpm = 900,
+ peakmaxrpm = 2800,
+ limitrpm = 4200
+} )
+
+ACF_DefineEngine( "4.1-I5", {
+ name = "4.1L I5 Diesel",
+ desc = "Heavier duty diesel, found in things that work hard",
+ model = "models/engines/inline5m.mdl",
+ sound = "acf_engines/i5_dieselmedium.wav",
+ category = "I5",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 400,
+ torque = 440,
+ flywheelmass = 1.5,
+ idlerpm = 650,
+ peakminrpm = 1000,
+ peakmaxrpm = 3200,
+ limitrpm = 3800
+} )
diff --git a/lua/acf/shared/engines/i6.lua b/lua/acf/shared/engines/i6.lua
new file mode 100644
index 000000000..249bda27d
--- /dev/null
+++ b/lua/acf/shared/engines/i6.lua
@@ -0,0 +1,108 @@
+
+-- Inline 6 engines
+
+-- Petrol
+
+ACF_DefineEngine( "2.2-I6", {
+ name = "2.2L I6 Petrol",
+ desc = "Car sized I6 petrol with power in the high revs",
+ model = "models/engines/inline6s.mdl",
+ sound = "acf_engines/l6_petrolsmall2.wav",
+ category = "I6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 120,
+ torque = 130,
+ flywheelmass = 0.1,
+ idlerpm = 800,
+ peakminrpm = 4000,
+ peakmaxrpm = 6500,
+ limitrpm = 7200
+} )
+
+ACF_DefineEngine( "4.8-I6", {
+ name = "4.8L I6 Petrol",
+ desc = "Light truck duty I6, good for offroad applications",
+ model = "models/engines/inline6m.mdl",
+ sound = "acf_engines/l6_petrolmedium.wav",
+ category = "I6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 300,
+ torque = 360,
+ flywheelmass = 0.2,
+ idlerpm = 900,
+ peakminrpm = 3100,
+ peakmaxrpm = 5000,
+ limitrpm = 5500
+} )
+
+ACF_DefineEngine( "17.2-I6", {
+ name = "17.2L I6 Petrol",
+ desc = "Heavy tractor duty petrol I6, decent overall powerband",
+ model = "models/engines/inline6l.mdl",
+ sound = "acf_engines/l6_petrollarge2.wav",
+ category = "I6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 850,
+ torque = 960,
+ flywheelmass = 2.5,
+ idlerpm = 800,
+ peakminrpm = 2000,
+ peakmaxrpm = 4000,
+ limitrpm = 4250
+} )
+
+-- Diesel
+
+ACF_DefineEngine( "3.0-I6", {
+ name = "3.0L I6 Diesel",
+ desc = "Car sized I6 diesel, good, wide powerband",
+ model = "models/engines/inline6s.mdl",
+ sound = "acf_engines/l6_dieselsmall.wav",
+ category = "I6",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 150,
+ torque = 200,
+ flywheelmass = 0.5,
+ idlerpm = 650,
+ peakminrpm = 1000,
+ peakmaxrpm = 3000,
+ limitrpm = 4500
+} )
+
+ACF_DefineEngine( "6.5-I6", {
+ name = "6.5L I6 Diesel",
+ desc = "Truck duty I6, good overall powerband and torque",
+ model = "models/engines/inline6m.mdl",
+ sound = "acf_engines/l6_dieselmedium4.wav",
+ category = "I6",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 450,
+ torque = 520,
+ flywheelmass = 1.5,
+ idlerpm = 600,
+ peakminrpm = 1000,
+ peakmaxrpm = 3000,
+ limitrpm = 4000
+} )
+
+ACF_DefineEngine( "20.0-I6", {
+ name = "20.0L I6 Diesel",
+ desc = "Heavy duty diesel I6, used in generators and heavy movers",
+ model = "models/engines/inline6l.mdl",
+ sound = "acf_engines/l6_diesellarge2.wav",
+ category = "I6",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 1200,
+ torque = 1700,
+ flywheelmass = 8,
+ idlerpm = 400,
+ peakminrpm = 650,
+ peakmaxrpm = 2100,
+ limitrpm = 2600
+} )
diff --git a/lua/acf/shared/engines/radial.lua b/lua/acf/shared/engines/radial.lua
new file mode 100644
index 000000000..49258f34d
--- /dev/null
+++ b/lua/acf/shared/engines/radial.lua
@@ -0,0 +1,71 @@
+
+-- Radial engines
+
+ACF_DefineEngine( "3.8-R7", {
+ name = "3.8L R7 Petrol",
+ desc = "A tiny, old worn-out radial.",
+ model = "models/engines/radial7s.mdl",
+ sound = "acf_engines/r7_petrolsmall.wav",
+ category = "Radial",
+ fuel = "Petrol",
+ enginetype = "Radial",
+ weight = 210,
+ torque = 310,
+ flywheelmass = 0.22,
+ idlerpm = 700,
+ peakminrpm = 2600,
+ peakmaxrpm = 4350,
+ limitrpm = 4800
+} )
+
+ACF_DefineEngine( "11.0-R7", {
+ name = "11.0 R7 Petrol",
+ desc = "Mid range radial, thirsty and smooth",
+ model = "models/engines/radial7m.mdl",
+ sound = "acf_engines/r7_petrolmedium.wav",
+ category = "Radial",
+ fuel = "Petrol",
+ enginetype = "Radial",
+ weight = 385,
+ torque = 560,
+ flywheelmass = 0.45,
+ idlerpm = 600,
+ peakminrpm = 2300,
+ peakmaxrpm = 3850,
+ limitrpm = 4400
+} )
+
+
+ACF_DefineEngine( "8.0-R7", {
+ name = "8.0 R7 Diesel",
+ desc = "Military-grade radial engine, similar to a ZO 02A. Heavy and with a narrow powerband, but efficient, and well-optimized to cruising.",
+ model = "models/engines/radial7m.mdl",
+ sound = "acf_engines/r7_petrolmedium.wav",
+ category = "Radial",
+ fuel = "Multifuel",
+ enginetype = "GenericDiesel",
+ weight = 450,
+ torque = 800,
+ flywheelmass = 1.0,
+ idlerpm = 400,
+ peakminrpm = 2200,
+ peakmaxrpm = 2500,
+ limitrpm = 2800
+} )
+
+ACF_DefineEngine( "24.0-R7", {
+ name = "24.0L R7 Petrol",
+ desc = "Massive American radial monster, destined for fighter aircraft and heavy tanks.",
+ model = "models/engines/radial7l.mdl",
+ sound = "acf_engines/r7_petrollarge.wav",
+ category = "Radial",
+ fuel = "Petrol",
+ enginetype = "Radial",
+ weight = 952,
+ torque = 1615,
+ flywheelmass = 3.4,
+ idlerpm = 750,
+ peakminrpm = 1900,
+ peakmaxrpm = 3150,
+ limitrpm = 3500
+} )
diff --git a/lua/acf/shared/engines/rotary.lua b/lua/acf/shared/engines/rotary.lua
new file mode 100644
index 000000000..5f852b649
--- /dev/null
+++ b/lua/acf/shared/engines/rotary.lua
@@ -0,0 +1,53 @@
+
+-- Wankel engines
+
+ACF_DefineEngine( "900cc-R", {
+ name = "0.9L Rotary",
+ desc = "Small 2-rotor Wankel; suited for yard use\n\nWankels have rather wide powerbands, but are very high strung",
+ model = "models/engines/wankel_2_small.mdl",
+ sound = "acf_engines/wankel_small.wav",
+ category = "Rotary",
+ fuel = "Petrol",
+ enginetype = "Wankel",
+ weight = 50,
+ torque = 78,
+ flywheelmass = 0.06,
+ idlerpm = 950,
+ peakminrpm = 4500,
+ peakmaxrpm = 9000,
+ limitrpm = 9200
+} )
+
+ACF_DefineEngine( "1.3L-R", {
+ name = "1.3L Rotary",
+ desc = "Medium 2-rotor Wankel\n\nWankels have rather wide powerbands, but are very high strung",
+ model = "models/engines/wankel_2_med.mdl",
+ sound = "acf_engines/wankel_medium.wav",
+ category = "Rotary",
+ fuel = "Petrol",
+ enginetype = "Wankel",
+ weight = 140,
+ torque = 124,
+ flywheelmass = 0.06,
+ idlerpm = 950,
+ peakminrpm = 4100,
+ peakmaxrpm = 8500,
+ limitrpm = 9000
+} )
+
+ACF_DefineEngine( "2.0L-R", {
+ name = "2.0L Rotary",
+ desc = "High performance 3-rotor Wankel\n\nWankels have rather wide powerbands, but are very high strung",
+ model = "models/engines/wankel_3_med.mdl",
+ sound = "acf_engines/wankel_large.wav",
+ category = "Rotary",
+ fuel = "Petrol",
+ enginetype = "Wankel",
+ weight = 200,
+ torque = 188,
+ flywheelmass = 0.1,
+ idlerpm = 950,
+ peakminrpm = 4100,
+ peakmaxrpm = 8500,
+ limitrpm = 9500
+} )
diff --git a/lua/acf/shared/engines/single.lua b/lua/acf/shared/engines/single.lua
new file mode 100644
index 000000000..ad875bd08
--- /dev/null
+++ b/lua/acf/shared/engines/single.lua
@@ -0,0 +1,53 @@
+
+-- Single-cylinder engines
+
+ACF_DefineEngine( "0.25-I1", {
+ name = "250cc Single",
+ desc = "Tiny bike engine",
+ model = "models/engines/1cylsml.mdl",
+ sound = "acf_engines/i1_small.wav",
+ category = "Single",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 15,
+ torque = 20,
+ flywheelmass = 0.005,
+ idlerpm = 1200,
+ peakminrpm = 4000,
+ peakmaxrpm = 6500,
+ limitrpm = 7500
+} )
+
+ACF_DefineEngine( "0.5-I1", {
+ name = "500cc Single",
+ desc = "Large single cylinder bike engine",
+ model = "models/engines/1cylmed.mdl",
+ sound = "acf_engines/i1_medium.wav",
+ category = "Single",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 20,
+ torque = 40,
+ flywheelmass = 0.005,
+ idlerpm = 900,
+ peakminrpm = 4300,
+ peakmaxrpm = 7000,
+ limitrpm = 8000
+} )
+
+ACF_DefineEngine( "1.3-I1", {
+ name = "1300cc Single",
+ desc = "Ridiculously large single cylinder engine, seriously what the fuck",
+ model = "models/engines/1cylbig.mdl",
+ sound = "acf_engines/i1_large.wav",
+ category = "Single",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 50,
+ torque = 90,
+ flywheelmass = 0.1,
+ idlerpm = 600,
+ peakminrpm = 3600,
+ peakmaxrpm = 6000,
+ limitrpm = 6700
+} )
diff --git a/lua/acf/shared/engines/special.lua b/lua/acf/shared/engines/special.lua
new file mode 100644
index 000000000..f94595dda
--- /dev/null
+++ b/lua/acf/shared/engines/special.lua
@@ -0,0 +1,203 @@
+
+-- Special engines
+
+ACF_DefineEngine( "0.9L-I2", {
+ name = "0.9L I2 Petrol",
+ desc = "Turbocharged inline twin engine that delivers surprising pep for its size.",
+ model = "models/engines/inline2s.mdl",
+ sound = "acf_extra/vehiclefx/engines/ponyengine.wav",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 60,
+ torque = 116,
+ flywheelmass = 0.085,
+ idlerpm = 750,
+ peakminrpm = 3125,
+ peakmaxrpm = 5100,
+ limitrpm = 6000
+} )
+
+ACF_DefineEngine( "1.0L-I4", {
+ name = "1.0L I4 Petrol",
+ desc = "Tiny I4 designed for racing bikes. Doesn't pack much torque, but revs ludicrously high.",
+ model = "models/engines/inline4s.mdl",
+ sound = "acf_extra/vehiclefx/engines/l4/mini_onhigh.wav",
+ pitch = 0.75,
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 78,
+ torque = 68,
+ flywheelmass = 0.031,
+ idlerpm = 1200,
+ peakminrpm = 7500,
+ peakmaxrpm = 11500,
+ limitrpm = 12000
+} )
+
+ACF_DefineEngine( "1.8L-V4", {
+ name = "1.8L V4 Petrol",
+ desc = "Naturally aspirated rally-tuned V4 with enlarged bore and stroke.",
+ model = "models/engines/v4s.mdl",
+ sound = "acf_extra/vehiclefx/engines/l4/elan_onlow.WAV",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 92,
+ torque = 124.8,
+ flywheelmass = 0.04,
+ idlerpm = 900,
+ peakminrpm = 4600,
+ peakmaxrpm = 7000,
+ limitrpm = 7500
+} )
+
+ACF_DefineEngine( "2.4L-V6", {
+ name = "2.4L V6 Petrol",
+ desc = "Although the cast iron engine block is fairly weighty, this tiny v6 makes up for it with impressive power. The unique V angle allows uncharacteristically high RPM for a V6.",
+ model = "models/engines/v6small.mdl",
+ sound = "acf_extra/vehiclefx/engines/l6/capri_onmid.WAV",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 134,
+ torque = 172,
+ flywheelmass = 0.075,
+ idlerpm = 950,
+ peakminrpm = 4500,
+ peakmaxrpm = 7100,
+ limitrpm = 8000
+} )
+
+ACF_DefineEngine( "1.9L-I4", {
+ name = "1.9L I4 Petrol",
+ desc = "Supercharged racing 4 cylinder, most of the power in the high revs.",
+ model = "models/engines/inline4s.mdl",
+ sound = "acf_engines/i4_special.wav",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 150,
+ torque = 176,
+ flywheelmass = 0.06,
+ idlerpm = 950,
+ peakminrpm = 5200,
+ peakmaxrpm = 8500,
+ limitrpm = 9000
+} )
+
+ACF_DefineEngine( "2.6L-Wankel", {
+ name = "2.6L Rotary",
+ desc = "4 rotor racing Wankel, high revving and high strung.",
+ model = "models/engines/wankel_4_med.mdl",
+ sound = "acf_engines/wankel_large.wav",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "Wankel",
+ requiresfuel = true,
+ weight = 260,
+ torque = 250,
+ flywheelmass = 0.11,
+ idlerpm = 1200,
+ peakminrpm = 4500,
+ peakmaxrpm = 9000,
+ limitrpm = 9500
+} )
+
+ACF_DefineEngine( "2.9-V8", {
+ name = "2.9L V8 Petrol",
+ desc = "Racing V8, very high revving and loud",
+ model = "models/engines/v8s.mdl",
+ sound = "acf_engines/v8_special.wav",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 180,
+ torque = 200,
+ flywheelmass = 0.075,
+ idlerpm = 1000,
+ peakminrpm = 5500,
+ peakmaxrpm = 9000,
+ limitrpm = 10000
+} )
+
+ACF_DefineEngine( "3.8-I6", {
+ name = "3.8L I6 Petrol",
+ desc = "Large racing straight six, powerful and high revving, but lacking in torque.",
+ model = "models/engines/inline6m.mdl",
+ sound = "acf_engines/l6_special.wav",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 180,
+ torque = 224,
+ flywheelmass = 0.1,
+ idlerpm = 1100,
+ peakminrpm = 5200,
+ peakmaxrpm = 8500,
+ limitrpm = 9000
+} )
+
+ACF_DefineEngine( "5.3-V10", {
+ name = "5.3L V10 Special",
+ desc = "Extreme performance v10",
+ model = "models/engines/v10sml.mdl",
+ sound = "acf_engines/v10_special.wav",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 300,
+ torque = 320,
+ requiresfuel = true,
+ flywheelmass = 0.15,
+ idlerpm = 1100,
+ peakminrpm = 5750,
+ peakmaxrpm = 8000,
+ limitrpm = 9000
+} )
+
+ACF_DefineEngine( "7.2-V8", {
+ name = "7.2L V8 Petrol",
+ desc = "Very high revving, glorious v8 of ear rapetasticalness.",
+ model = "models/engines/v8m.mdl",
+ sound = "acf_engines/v8_special2.wav",
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 400,
+ torque = 340,
+ flywheelmass = 0.15,
+ idlerpm = 1000,
+ peakminrpm = 5000,
+ peakmaxrpm = 8000,
+ limitrpm = 8500
+} )
+
+ACF_DefineEngine( "3.0-V12", {
+ name = "3.0L V12 Petrol",
+ desc = "A purpose-built racing v12, not known for longevity.",
+ model = "models/engines/v12s.mdl",
+ sound = "acf_extra/vehiclefx/engines/v12/gtb4_onmid.WAV",
+ pitch = 0.85,
+ category = "Special",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 175,
+ torque = 248,
+ flywheelmass = 0.1,
+ idlerpm = 1200,
+ peakminrpm = 6875,
+ peakmaxrpm = 11000,
+ limitrpm = 12500
+} )
+
diff --git a/lua/acf/shared/engines/touring.lua b/lua/acf/shared/engines/touring.lua
new file mode 100644
index 000000000..cbc77a4b6
--- /dev/null
+++ b/lua/acf/shared/engines/touring.lua
@@ -0,0 +1,235 @@
+
+-- Touring car engines for Avtomat events 2021
+
+
+--I4
+ACF_DefineEngine( "1.6-I4T", {
+ name = "1.6L I4T Petrol",
+ desc = "1.6L turbocharged touring car engine",
+ model = "models/engines/inline4s.mdl",
+ sound = "acf_extra/vehiclefx/engines/l4/mini_onhigh.wav",
+ pitch = 0.75,
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 82,
+ torque = 258*1.2,
+ flywheelmass = 0.041,
+ idlerpm = 1100,
+ peakminrpm = 4000,
+ peakmaxrpm = 7000,
+ limitrpm = 8800
+} )
+
+ACF_DefineEngine( "2.5-I4T", {
+ name = "2.5L I4T Petrol",
+ desc = "2.5L turbocharged I4 touring car engine",
+ model = "models/engines/inline4s.mdl",
+ sound = "acf_extra/vehiclefx/engines/l4/mini_onhigh.wav",
+ pitch = 0.75,
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 129,
+ torque = 330*1.2,
+ flywheelmass = 0.1,
+ idlerpm = 1100,
+ peakminrpm = 3700,
+ peakmaxrpm = 6620,
+ limitrpm = 7500
+} )
+
+ACF_DefineEngine( "2.5-I4", {
+ name = "2.5L I4 Petrol",
+ desc = "2.5L I4 touring car engine",
+ model = "models/engines/inline4s.mdl",
+ sound = "acf_extra/vehiclefx/engines/l4/mini_onhigh.wav",
+ pitch = 0.75,
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 97,
+ torque = 237.5*1.2,
+ flywheelmass = 0.1,
+ idlerpm = 900,
+ peakminrpm = 3500,
+ peakmaxrpm = 6000,
+ limitrpm = 7200
+} )
+
+--B4
+ACF_DefineEngine( "2.5-B4T", {
+ name = "2.5L B4T Petrol",
+ desc = "2.5L turbocharged B4 touring car engine",
+ model = "models/engines/b4small.mdl",
+ sound = "acf_engines/b4_petrolmedium.wav",
+ pitch = 0.75,
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 119,
+ torque = 330*1.2,
+ flywheelmass = 0.09,
+ idlerpm = 1000,
+ peakminrpm = 3800,
+ peakmaxrpm = 6620,
+ limitrpm = 8000
+} )
+
+ACF_DefineEngine( "2.5-B4", {
+ name = "2.5L B4 Petrol",
+ desc = "2.5L B4 touring car engine",
+ model = "models/engines/b4small.mdl",
+ sound = "acf_engines/b4_petrolmedium.wav",
+ pitch = 0.75,
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 90,
+ torque = 237.5*1.2,
+ flywheelmass = 0.09,
+ idlerpm = 940,
+ peakminrpm = 3600,
+ peakmaxrpm = 6000,
+ limitrpm = 8000
+} )
+
+
+--V6
+ACF_DefineEngine( "2.5L-V6", {
+ name = "2.5L V6 Petrol",
+ desc = "Touring car 300hp class engine",
+ model = "models/engines/v6small.mdl",
+ sound = "acf_extra/vehiclefx/engines/l6/capri_onmid.WAV",
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 150,
+ torque = 246*1.2,
+ flywheelmass = 0.075,
+ idlerpm = 1000,
+ peakminrpm = 3600,
+ peakmaxrpm = 5800,
+ limitrpm = 7500
+} )
+
+
+ACF_DefineEngine( "2.5L-V6T", {
+ name = "2.5L V6T Petrol",
+ desc = "2.5L turbocharged V6 touring car engine",
+ model = "models/engines/v6small.mdl",
+ sound = "acf_extra/vehiclefx/engines/l6/capri_onmid.WAV",
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 180,
+ torque = 336.5*1.2,
+ flywheelmass = 0.075,
+ idlerpm = 1250,
+ peakminrpm = 4500,
+ peakmaxrpm = 6500,
+ limitrpm = 7200
+} )
+
+--I6
+ACF_DefineEngine( "2.5L-I6", {
+ name = "2.5L I6 Petrol",
+ desc = "2.5L I6 touring car engine",
+ model = "models/engines/inline6s.mdl",
+ sound = "acf_extra/vehiclefx/engines/l6/capri_onmid.WAV",
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 160,
+ torque = 230*1.2,
+ flywheelmass = 0.065,
+ idlerpm = 870,
+ peakminrpm = 3400,
+ peakmaxrpm = 6200,
+ limitrpm = 8000
+} )
+
+
+ACF_DefineEngine( "2.5L-I6T", {
+ name = "2.5L I6T Petrol",
+ desc = "2.5L turbocharged I6 touring car engine",
+ model = "models/engines/inline6s.mdl",
+ sound = "acf_extra/vehiclefx/engines/l6/capri_onmid.WAV",
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 180,
+ torque = 321.5*1.2,
+ flywheelmass = 0.065,
+ idlerpm = 1080,
+ peakminrpm = 4000,
+ peakmaxrpm = 6800,
+ limitrpm = 8000
+} )
+
+--I5
+ACF_DefineEngine( "2.5L-I5", {
+ name = "2.5L I5 Petrol",
+ desc = "2.5L I5 touring car engine",
+ model = "models/engines/inline5s.mdl",
+ sound = "acf_engines/i5_petrolsmall.wav",
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 130,
+ torque = 237.5*1.2,
+ flywheelmass = 0.1,
+ idlerpm = 900,
+ peakminrpm = 3300,
+ peakmaxrpm = 6000,
+ limitrpm = 7000
+} )
+
+
+ACF_DefineEngine( "2.5L-I5T", {
+ name = "2.5L I5T Petrol",
+ desc = "2.5L turbocharged I5 touring car engine",
+ model = "models/engines/inline5s.mdl",
+ sound = "acf_engines/i5_petrolsmall.wav",
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 160,
+ torque = 340.5*1.2,
+ flywheelmass = 0.1,
+ idlerpm = 900,
+ peakminrpm = 4400,
+ peakmaxrpm = 6420,
+ limitrpm = 6900
+} )
+
+
+--V8
+ACF_DefineEngine( "4.0L-V8", {
+ name = "4.0L V8 Petrol",
+ desc = "4.0L V8 touring car engine",
+ model = "models/engines/v8s.mdl",
+ sound = "acf_engines/v8_petrolsmall.wav",
+ category = "Touring",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ requiresfuel = true,
+ weight = 200,
+ torque = 330*1.2,
+ flywheelmass = 0.14,
+ idlerpm = 900,
+ peakminrpm = 4000,
+ peakmaxrpm = 6620,
+ limitrpm = 8500
+} )
\ No newline at end of file
diff --git a/lua/acf/shared/engines/turbine.lua b/lua/acf/shared/engines/turbine.lua
new file mode 100644
index 000000000..0f5972351
--- /dev/null
+++ b/lua/acf/shared/engines/turbine.lua
@@ -0,0 +1,258 @@
+
+-- Gas turbines
+
+ACF_DefineEngine( "Turbine-Small-Trans", {
+ name = "Gas Turbine, Small, Transaxial",
+ desc = "A small gas turbine, high power and a very wide powerband\n\nThese turbines are optimized for aero use, but can be used in other specialized roles, being powerful but suffering from poor throttle response and fuel consumption.\n\nOutputs to the side instead of rear.",
+ model = "models/engines/turbine_s.mdl",
+ sound = "acf_engines/turbine_small.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Turbine",
+ requiresfuel = true,
+ weight = 160,
+ torque = 440,
+ flywheelmass = 2.3,
+ idlerpm = 1400,
+ peakminrpm = 1000,
+ peakmaxrpm = 1500,
+ limitrpm = 10000,
+ iselec = true,
+ istrans = true,
+ flywheeloverride = 4167
+} )
+
+ACF_DefineEngine( "Turbine-Medium-Trans", {
+ name = "Gas Turbine, Medium, Transaxial",
+ desc = "A medium gas turbine, moderate power but a very wide powerband\n\nThese turbines are optimized for aero use, but can be used in other specialized roles, being powerful but suffering from poor throttle response and fuel consumption.\n\nOutputs to the side instead of rear.",
+ model = "models/engines/turbine_m.mdl",
+ sound = "acf_engines/turbine_medium.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Turbine",
+ requiresfuel = true,
+ weight = 320,
+ torque = 650,
+ flywheelmass = 3.4,
+ idlerpm = 1800,
+ peakminrpm = 1200,
+ peakmaxrpm = 1800,
+ limitrpm = 12000,
+ iselec = true,
+ istrans = true,
+ flywheeloverride = 5000
+} )
+
+ACF_DefineEngine( "Turbine-Large-Trans", {
+ name = "Gas Turbine, Large, Transaxial",
+ desc = "A large gas turbine, powerful with a wide powerband\n\nThese turbines are optimized for aero use, but can be used in other specialized roles, being powerful but suffering from poor throttle response and fuel consumption.\n\nOutputs to the side instead of rear.",
+ model = "models/engines/turbine_l.mdl",
+ sound = "acf_engines/turbine_large.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Turbine",
+ requiresfuel = true,
+ weight = 880,
+ torque = 1592,
+ flywheelmass = 8.4,
+ idlerpm = 2000,
+ peakminrpm = 1350,
+ peakmaxrpm = 2025,
+ limitrpm = 13500,
+ iselec = true,
+ istrans = true,
+ flywheeloverride = 5625
+} )
+
+ACF_DefineEngine( "Turbine-Small", {
+ name = "Gas Turbine, Small",
+ desc = "A small gas turbine, high power and a very wide powerband\n\nThese turbines are optimized for aero use, but can be used in other specialized roles, being powerful but suffering from poor throttle response and fuel consumption.",
+ model = "models/engines/gasturbine_s.mdl",
+ sound = "acf_engines/turbine_small.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Turbine",
+ requiresfuel = true,
+ weight = 200,
+ torque = 550,
+ flywheelmass = 2.9,
+ idlerpm = 1400,
+ peakminrpm = 1000,
+ peakmaxrpm = 1500,
+ limitrpm = 10000,
+ iselec = true,
+ flywheeloverride = 4167
+} )
+
+ACF_DefineEngine( "Turbine-Medium", {
+ name = "Gas Turbine, Medium",
+ desc = "A medium gas turbine, moderate power but a very wide powerband\n\nThese turbines are optimized for aero use, but can be used in other specialized roles, being powerful but suffering from poor throttle response and fuel consumption.",
+ model = "models/engines/gasturbine_m.mdl",
+ sound = "acf_engines/turbine_medium.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Turbine",
+ requiresfuel = true,
+ weight = 400,
+ torque = 813,
+ flywheelmass = 4.3,
+ idlerpm = 1800,
+ peakminrpm = 1200,
+ peakmaxrpm = 1800,
+ limitrpm = 12000,
+ iselec = true,
+ flywheeloverride = 5000
+} )
+
+ACF_DefineEngine( "Turbine-Large", {
+ name = "Gas Turbine, Large",
+ desc = "A large gas turbine, powerful with a wide powerband\n\nThese turbines are optimized for aero use, but can be used in other specialized roles, being powerful but suffering from poor throttle response and fuel consumption.",
+ model = "models/engines/gasturbine_l.mdl",
+ sound = "acf_engines/turbine_large.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Turbine",
+ requiresfuel = true,
+ weight = 1100,
+ torque = 1990,
+ flywheelmass = 10.5,
+ idlerpm = 2000,
+ peakminrpm = 1350,
+ peakmaxrpm = 2025,
+ limitrpm = 13500,
+ iselec = true,
+ flywheeloverride = 5625
+} )
+
+--Forward facing ground turbines
+
+ACF_DefineEngine( "Turbine-Ground-Small", {
+ name = "Ground Gas Turbine, Small",
+ desc = "A small gas turbine, fitted with ground-use air filters and tuned for ground use.\n\nGround-use turbines have excellent low-rev performance and are deceptively powerful, easily propelling loads that would have equivalent reciprocating engines struggling; however, they have sluggish throttle response, high gearbox demands, high fuel usage, and low tolerance to damage.",
+ model = "models/engines/gasturbine_s.mdl",
+ sound = "acf_engines/turbine_small.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Radial",
+ requiresfuel = true,
+ weight = 350,
+ torque = 800,
+ flywheelmass = 14.3,
+ idlerpm = 700,
+ peakminrpm = 1000,
+ peakmaxrpm = 1350,
+ limitrpm = 3000,
+ iselec = true,
+ flywheeloverride = 1667
+} )
+
+ACF_DefineEngine( "Turbine-Ground-Medium", {
+ name = "Ground Gas Turbine, Medium",
+ desc = "A medium gas turbine, fitted with ground-use air filters and tuned for ground use.\n\nGround-use turbines have excellent low-rev performance and are deceptively powerful, easily propelling loads that would have equivalent reciprocating engines struggling; however, they have sluggish throttle response, high gearbox demands, high fuel usage, and low tolerance to damage.",
+ model = "models/engines/gasturbine_m.mdl",
+ sound = "acf_engines/turbine_medium.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Radial", --This is done to give proper fuel consumption and make the turbines not instant-torque from idle
+ requiresfuel = true,
+ weight = 600,
+ torque = 1200,
+ flywheelmass = 29.6,
+ idlerpm = 600,
+ peakminrpm = 1500,
+ peakmaxrpm = 2000,
+ limitrpm = 3000,
+ iselec = true,
+ flywheeloverride = 1450,
+ pitch = 1.15
+} )
+
+ACF_DefineEngine( "Turbine-Ground-Large", {
+ name = "Ground Gas Turbine, Large",
+ desc = "A large gas turbine, fitted with ground-use air filters and tuned for ground use. Doesn't have the sheer power output of an aero gas turbine, but compensates with an imperial fuckload of torque.\n\nGround-use turbines have excellent low-rev performance and are deceptively powerful, easily propelling loads that would have equivalent reciprocating engines struggling; however, they have sluggish throttle response, high gearbox demands, high fuel usage, and low tolerance to damage.",
+ model = "models/engines/gasturbine_l.mdl",
+ sound = "acf_engines/turbine_large.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Radial",
+ requiresfuel = true,
+ weight = 1650,
+ torque = 4000,
+ flywheelmass = 75,
+ idlerpm = 500,
+ peakminrpm = 1000,
+ peakmaxrpm = 1250,
+ limitrpm = 3000,
+ iselec = true,
+ flywheeloverride = 1250,
+ pitch = 1.35
+} )
+
+--Transaxial Ground Turbines
+
+ACF_DefineEngine( "Turbine-Small-Ground-Trans", {
+ name = "Ground Gas Turbine, Small, Transaxial",
+ desc = "A small gas turbine, fitted with ground-use air filters and tuned for ground use.\n\nGround-use turbines have excellent low-rev performance and are deceptively powerful, easily propelling loads that would have equivalent reciprocating engines struggling; however, they have sluggish throttle response, high gearbox demands, high fuel usage, and low tolerance to damage. Outputs to the side instead of rear.",
+ model = "models/engines/turbine_s.mdl",
+ sound = "acf_engines/turbine_small.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Radial",
+ requiresfuel = true,
+ weight = 280,
+ torque = 600,
+ flywheelmass = 11.4,
+ idlerpm = 700,
+ peakminrpm = 1000,
+ peakmaxrpm = 1350,
+ limitrpm = 3000,
+ iselec = true,
+ istrans = true,
+ flywheeloverride = 1667
+} )
+
+ACF_DefineEngine( "Turbine-Medium-Ground-Trans", {
+ name = "Ground Gas Turbine, Medium, Transaxial",
+ desc = "A medium gas turbine, fitted with ground-use air filters and tuned for ground use.\n\nGround-use turbines have excellent low-rev performance and are deceptively powerful, easily propelling loads that would have equivalent reciprocating engines struggling; however, they have sluggish throttle response, high gearbox demands, high fuel usage, and low tolerance to damage. Outputs to the side instead of rear.",
+ model = "models/engines/turbine_m.mdl",
+ sound = "acf_engines/turbine_medium.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Radial",
+ requiresfuel = true,
+ weight = 480,
+ torque = 900,
+ flywheelmass = 23.7,
+ idlerpm = 600,
+ peakminrpm = 1500,
+ peakmaxrpm = 2000,
+ limitrpm = 3000,
+ iselec = true,
+ istrans = true,
+ flywheeloverride = 1450,
+ pitch = 1.15
+} )
+
+ACF_DefineEngine( "Turbine-Large-Ground-Trans", {
+ name = "Ground Gas Turbine, Large, Transaxial",
+ desc = "A large gas turbine, fitted with ground-use air filters and tuned for ground use. Doesn't have the sheer power output of an aero gas turbine, but compensates with an imperial fuckload of torque.\n\nGround-use turbines have excellent low-rev performance and are deceptively powerful, easily propelling loads that would have equivalent reciprocating engines struggling; however, they have sluggish throttle response, high gearbox demands, high fuel usage, and low tolerance to damage. Outputs to the side instead of rear.",
+ model = "models/engines/turbine_l.mdl",
+ sound = "acf_engines/turbine_large.wav",
+ category = "Turbine",
+ fuel = "Multifuel",
+ enginetype = "Radial",
+ requiresfuel = true,
+ weight = 1320,
+ torque = 3000,
+ flywheelmass = 60,
+ idlerpm = 500,
+ peakminrpm = 1000,
+ peakmaxrpm = 1250,
+ limitrpm = 3000,
+ iselec = true,
+ istrans = true,
+ flywheeloverride = 1250,
+ pitch = 1.35
+} )
+
+
diff --git a/lua/acf/shared/engines/v10.lua b/lua/acf/shared/engines/v10.lua
new file mode 100644
index 000000000..99da94f01
--- /dev/null
+++ b/lua/acf/shared/engines/v10.lua
@@ -0,0 +1,52 @@
+--V10s
+
+ACF_DefineEngine( "4.3-V10", {
+ name = "4.3L V10 Petrol",
+ desc = "Small-block V-10 gasoline engine, great for powering a hot rod lincoln",
+ model = "models/engines/v10sml.mdl",
+ sound = "acf_engines/v10_petrolsmall.wav",
+ category = "V10",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 160,
+ torque = 288,
+ flywheelmass = 0.2,
+ idlerpm = 900,
+ peakminrpm = 3500,
+ peakmaxrpm = 5800,
+ limitrpm = 6250
+} )
+
+ACF_DefineEngine( "8.0-V10", {
+ name = "8.0L V10 Petrol",
+ desc = "Beefy 10-cylinder gas engine, gets 9 kids to soccer practice",
+ model = "models/engines/v10med.mdl",
+ sound = "acf_engines/v10_petrolmedium.wav",
+ category = "V10",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 300,
+ torque = 490,
+ flywheelmass = 0.5,
+ idlerpm = 750,
+ peakminrpm = 3400,
+ peakmaxrpm = 5500,
+ limitrpm = 6500
+} )
+
+ACF_DefineEngine( "22.0-V10", {
+ name = "22.0L V10 Multifuel",
+ desc = "Heavy multifuel V-10, gearbox-shredding torque but very heavy.",
+ model = "models/engines/v10big.mdl",
+ sound = "acf_engines/v10_diesellarge.wav",
+ category = "V10",
+ fuel = "Multifuel",
+ enginetype = "GenericDiesel",
+ weight = 1600,
+ torque = 2605,
+ flywheelmass = 5,
+ idlerpm = 525,
+ peakminrpm = 750,
+ peakmaxrpm = 1900,
+ limitrpm = 2500
+} )
diff --git a/lua/acf/shared/engines/v12.lua b/lua/acf/shared/engines/v12.lua
new file mode 100644
index 000000000..da182a136
--- /dev/null
+++ b/lua/acf/shared/engines/v12.lua
@@ -0,0 +1,125 @@
+
+-- V12 engines
+
+-- Petrol
+
+ACF_DefineEngine( "4.6-V12", {
+ name = "4.6L V12 Petrol",
+ desc = "An elderly racecar engine; low on torque, but plenty of power",
+ model = "models/engines/v12s.mdl",
+ sound = "acf_engines/v12_petrolsmall.wav",
+ category = "V12",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 188,
+ torque = 235,
+ flywheelmass = 0.2,
+ idlerpm = 1000,
+ peakminrpm = 4500,
+ peakmaxrpm = 7500,
+ limitrpm = 8000
+} )
+
+ACF_DefineEngine( "7.0-V12", {
+ name = "7.0L V12 Petrol",
+ desc = "A high end V12; primarily found in very expensive cars",
+ model = "models/engines/v12m.mdl",
+ sound = "acf_engines/v12_petrolmedium.wav",
+ category = "V12",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 360,
+ torque = 500,
+ flywheelmass = 0.45,
+ idlerpm = 800,
+ peakminrpm = 3600,
+ peakmaxrpm = 6000,
+ limitrpm = 7500
+} )
+
+ACF_DefineEngine( "23.0-V12", {
+ name = "23.0L V12 Petrol",
+ desc = "A large, thirsty gasoline V12, found in early cold war tanks",
+ model = "models/engines/v12l.mdl",
+ sound = "acf_engines/v12_petrollarge.wav",
+ category = "V12",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 1350,
+ torque = 1925,
+ flywheelmass = 5,
+ idlerpm = 600,
+ peakminrpm = 1500,
+ peakmaxrpm = 3000,
+ limitrpm = 3250
+} )
+
+-- Diesel
+
+ACF_DefineEngine( "4.0-V12", {
+ name = "4.0L V12 Diesel",
+ desc = "Reliable truck-duty diesel; a lot of smooth torque",
+ model = "models/engines/v12s.mdl",
+ sound = "acf_engines/v12_dieselsmall.wav",
+ category = "V12",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 305,
+ torque = 375,
+ flywheelmass = 0.475,
+ idlerpm = 650,
+ peakminrpm = 1200,
+ peakmaxrpm = 3800,
+ limitrpm = 4000
+} )
+
+ACF_DefineEngine( "9.2-V12", {
+ name = "9.2L V12 Diesel",
+ desc = "High torque light-tank V12, used mainly for vehicles that require balls",
+ model = "models/engines/v12m.mdl",
+ sound = "acf_engines/v12_dieselmedium.wav",
+ category = "V12",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 600,
+ torque = 750,
+ flywheelmass = 2.5,
+ idlerpm = 675,
+ peakminrpm = 1100,
+ peakmaxrpm = 3300,
+ limitrpm = 3500
+} )
+
+ACF_DefineEngine( "21.0-V12", {
+ name = "21.0L V12 Diesel",
+ desc = "AVDS-1790-2 tank engine; massively powerful, but enormous and heavy",
+ model = "models/engines/v12l.mdl",
+ sound = "acf_engines/v12_diesellarge.wav",
+ category = "V12",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 1800,
+ torque = 3560,
+ flywheelmass = 7,
+ idlerpm = 400,
+ peakminrpm = 500,
+ peakmaxrpm = 1500,
+ limitrpm = 2500
+} )
+
+ACF_DefineEngine( "13.0-V12", {
+ name = "13.0L V12 Petrol",
+ desc = "Thirsty gasoline v12, good torque and power for medium applications.",
+ model = "models/engines/v12m.mdl",
+ sound = "acf_engines/v12_special.wav",
+ category = "V12",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 520,
+ torque = 660,
+ flywheelmass = 1,
+ idlerpm = 700,
+ peakminrpm = 2500,
+ peakmaxrpm = 4000,
+ limitrpm = 4250
+} )
diff --git a/lua/acf/shared/engines/v2.lua b/lua/acf/shared/engines/v2.lua
new file mode 100644
index 000000000..89e7a1497
--- /dev/null
+++ b/lua/acf/shared/engines/v2.lua
@@ -0,0 +1,53 @@
+
+-- V-Twin engines
+
+ACF_DefineEngine( "0.6-V2", {
+ name = "600cc V-Twin",
+ desc = "Twin cylinder bike engine, torquey for its size",
+ model = "models/engines/v-twins2.mdl",
+ sound = "acf_engines/vtwin_small.wav",
+ category = "V-Twin",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 30,
+ torque = 50,
+ flywheelmass = 0.01,
+ idlerpm = 900,
+ peakminrpm = 4000,
+ peakmaxrpm = 6500,
+ limitrpm = 7000
+} )
+
+ACF_DefineEngine( "1.2-V2", {
+ name = "1200cc V-Twin",
+ desc = "Large displacement vtwin engine",
+ model = "models/engines/v-twinm2.mdl",
+ sound = "acf_engines/vtwin_medium.wav",
+ category = "V-Twin",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 50,
+ torque = 85,
+ flywheelmass = 0.02,
+ idlerpm = 725,
+ peakminrpm = 3300,
+ peakmaxrpm = 5500,
+ limitrpm = 6250
+} )
+
+ACF_DefineEngine( "2.4-V2", {
+ name = "2400cc V-Twin",
+ desc = "Huge fucking Vtwin 'MURRICA FUCK YEAH",
+ model = "models/engines/v-twinl2.mdl",
+ sound = "acf_engines/vtwin_large.wav",
+ category = "V-Twin",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 100,
+ torque = 160,
+ flywheelmass = 0.075,
+ idlerpm = 900,
+ peakminrpm = 3300,
+ peakmaxrpm = 5500,
+ limitrpm = 6000
+} )
diff --git a/lua/acf/shared/engines/v4.lua b/lua/acf/shared/engines/v4.lua
new file mode 100644
index 000000000..f027dfa98
--- /dev/null
+++ b/lua/acf/shared/engines/v4.lua
@@ -0,0 +1,38 @@
+
+--V4 Engines
+
+--Diesel
+
+ACF_DefineEngine( "1.9L-V4", {
+ name = "1.9L V4 Diesel",
+ desc = "Torquey little lunchbox; for those smaller vehicles that don't agree with petrol powerbands",
+ model = "models/engines/v4s.mdl",
+ sound = "acf_engines/i4_diesel2.wav",
+ category = "V4",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 110,
+ torque = 165,
+ flywheelmass = 0.3,
+ idlerpm = 650,
+ peakminrpm = 950,
+ peakmaxrpm = 3000,
+ limitrpm = 4000
+} )
+
+ACF_DefineEngine( "3.3L-V4", {
+ name = "3.3L V4 Diesel",
+ desc = "Compact cube of git; for moderate utility applications",
+ model = "models/engines/v4m.mdl",
+ sound = "acf_engines/i4_dieselmedium.wav",
+ category = "V4",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 275,
+ torque = 480,
+ flywheelmass = 1.05,
+ idlerpm = 600,
+ peakminrpm = 1050,
+ peakmaxrpm = 3100,
+ limitrpm = 3900
+} )
diff --git a/lua/acf/shared/engines/v6.lua b/lua/acf/shared/engines/v6.lua
new file mode 100644
index 000000000..541b91821
--- /dev/null
+++ b/lua/acf/shared/engines/v6.lua
@@ -0,0 +1,87 @@
+
+-- V6 engines
+
+ACF_DefineEngine( "3.6-V6", {
+ name = "3.6L V6 Petrol",
+ desc = "Meaty Car sized V6, lots of torque\n\nV6s are more torquey than the Boxer and Inline 6s but suffer in power",
+ model = "models/engines/v6small.mdl",
+ sound = "acf_engines/v6_petrolsmall.wav",
+ category = "V6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 190,
+ torque = 253,
+ flywheelmass = 0.25,
+ idlerpm = 700,
+ peakminrpm = 2200,
+ peakmaxrpm = 3500,
+ limitrpm = 5000
+} )
+
+ACF_DefineEngine( "6.2-V6", {
+ name = "6.2L V6 Petrol",
+ desc = "Heavy duty 6V71 v6, throatier than an LA whore, but loaded with torque\n\nV6s are more torquey than the Boxer and Inline 6s but suffer in power",
+ model = "models/engines/v6med.mdl",
+ sound = "acf_engines/v6_petrolmedium.wav",
+ category = "V6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 360,
+ torque = 472,
+ flywheelmass = 0.45,
+ idlerpm = 800,
+ peakminrpm = 2200,
+ peakmaxrpm = 3600,
+ limitrpm = 5000
+} )
+
+ACF_DefineEngine( "5.2-V6", {
+ name = "5.2L V6 Diesel",
+ desc = "Light AFV-grade two-stroke multifuel, high output but heavy",
+ model = "models/engines/v6med.mdl",
+ sound = "acf_engines/i5_dieselmedium.wav",
+ category = "V6",
+ fuel = "Multifuel",
+ enginetype = "GenericDiesel",
+ weight = 520,
+ torque = 485,
+ flywheelmass = 0.8,
+ idlerpm = 650,
+ peakminrpm = 1800,
+ peakmaxrpm = 4200,
+ limitrpm = 4300
+} )
+
+ACF_DefineEngine( "12.0-V6", {
+ name = "12.0L V6 Petrol",
+ desc = "Fuck duty V6, guts ripped from god himself diluted in salt and shaped into an engine.\n\nV6s are more torquey than the Boxer and Inline 6s but suffer in power",
+ model = "models/engines/v6large.mdl",
+ sound = "acf_engines/v6_petrollarge.wav",
+ category = "V6",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 675,
+ torque = 1445,
+ flywheelmass = 4,
+ idlerpm = 600,
+ peakminrpm = 1575,
+ peakmaxrpm = 2650,
+ limitrpm = 3800
+} )
+
+ACF_DefineEngine( "15.0-V6", {
+ name = "15.0L V6 Diesel",
+ desc = "Powerful military-grade large V6, with impressive output. Well suited to moderately-sized AFVs and able to handle multiple fuel types.\n\nV6s are more torquey than the Boxer and Inline 6s but suffer in power",
+ model = "models/engines/v6large.mdl",
+ sound = "acf_engines/v6_diesellarge.wav",
+ category = "V6",
+ fuel = "Multifuel",
+ enginetype = "GenericDiesel",
+ weight = 900,
+ torque = 1767,
+ flywheelmass = 6.4,
+ idlerpm = 400,
+ peakminrpm = 1150,
+ peakmaxrpm = 1950,
+ limitrpm = 3100
+} )
diff --git a/lua/acf/shared/engines/v8.lua b/lua/acf/shared/engines/v8.lua
new file mode 100644
index 000000000..79ae5c246
--- /dev/null
+++ b/lua/acf/shared/engines/v8.lua
@@ -0,0 +1,108 @@
+
+-- V8 engines
+
+-- Petrol
+
+ACF_DefineEngine( "5.7-V8", {
+ name = "5.7L V8 Petrol",
+ desc = "Car sized petrol engine, good power and mid range torque",
+ model = "models/engines/v8s.mdl",
+ sound = "acf_engines/v8_petrolsmall.wav",
+ category = "V8",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 260,
+ torque = 320,
+ flywheelmass = 0.15,
+ idlerpm = 800,
+ peakminrpm = 3000,
+ peakmaxrpm = 5000,
+ limitrpm = 6500
+} )
+
+ACF_DefineEngine( "9.0-V8", {
+ name = "9.0L V8 Petrol",
+ desc = "Thirsty, giant V8, for medium applications",
+ model = "models/engines/v8m.mdl",
+ sound = "acf_engines/v8_petrolmedium.wav",
+ category = "V8",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 400,
+ torque = 460,
+ flywheelmass = 0.25,
+ idlerpm = 700,
+ peakminrpm = 3100,
+ peakmaxrpm = 5000,
+ limitrpm = 5500
+} )
+
+ACF_DefineEngine( "18.0-V8", {
+ name = "18.0L V8 Petrol",
+ desc = "American gasoline tank V8, good overall power and torque and fairly lightweight",
+ model = "models/engines/v8l.mdl",
+ sound = "acf_engines/v8_petrollarge.wav",
+ category = "V8",
+ fuel = "Petrol",
+ enginetype = "GenericPetrol",
+ weight = 850,
+ torque = 1458,
+ flywheelmass = 2.8,
+ idlerpm = 600,
+ peakminrpm = 2000,
+ peakmaxrpm = 3300,
+ limitrpm = 3800
+} )
+
+-- Diesel
+
+ACF_DefineEngine( "4.5-V8", {
+ name = "4.5L V8 Diesel",
+ desc = "Light duty diesel v8, good for light vehicles that require a lot of torque",
+ model = "models/engines/v8s.mdl",
+ sound = "acf_engines/v8_dieselsmall.wav",
+ category = "V8",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 320,
+ torque = 415,
+ flywheelmass = 0.75,
+ idlerpm = 800,
+ peakminrpm = 1000,
+ peakmaxrpm = 3000,
+ limitrpm = 5000
+} )
+
+ACF_DefineEngine( "7.8-V8", {
+ name = "7.8L V8 Diesel",
+ desc = "Redneck chariot material. Truck duty V8 diesel, has a good, wide powerband",
+ model = "models/engines/v8m.mdl",
+ sound = "acf_engines/v8_dieselmedium2.wav",
+ category = "V8",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 520,
+ torque = 700,
+ flywheelmass = 1.6,
+ idlerpm = 650,
+ peakminrpm = 1000,
+ peakmaxrpm = 3000,
+ limitrpm = 4000
+} )
+
+ACF_DefineEngine( "19.0-V8", {
+ name = "19.0L V8 Diesel",
+ desc = "Heavy duty diesel V8, used in heavy construction equipment and tanks",
+ model = "models/engines/v8l.mdl",
+ sound = "acf_engines/v8_diesellarge.wav",
+ category = "V8",
+ fuel = "Diesel",
+ enginetype = "GenericDiesel",
+ weight = 1200,
+ torque = 2300,
+ flywheelmass = 4.5,
+ idlerpm = 500,
+ peakminrpm = 600,
+ peakmaxrpm = 1800,
+ limitrpm = 2500
+} )
diff --git a/lua/acf/shared/fueltanks/basic.lua b/lua/acf/shared/fueltanks/basic.lua
new file mode 100644
index 000000000..158bf0409
--- /dev/null
+++ b/lua/acf/shared/fueltanks/basic.lua
@@ -0,0 +1,355 @@
+
+--definition for the fuel tank that shows on menu
+ACF_DefineFuelTank( "Basic_FuelTank", {
+ name = "High Grade Fuel Tank",
+ desc = "A fuel tank containing high grade fuel. Guaranteed to improve engine performance by "..((ACF.TorqueBoost-1)*100).."%.",
+ category = "High Grade"
+} )
+
+--definitions for the possible tank sizes selectable from the basic tank.
+ACF_DefineFuelTankSize( "Tank_1x1x1", { --ID used in code
+ name = "1x1x1", --human readable name
+ desc = "Seriously consider walking.",
+ model = "models/fueltank/fueltank_1x1x1.mdl",
+ dims = { S = 590.5, V = 1019.9 } --surface area and volume of prop in gmu, used for capacity calcs in gui
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x1x2", {
+ name = "1x1x2",
+ desc = "Will keep a kart running all day.",
+ model = "models/fueltank/fueltank_1x1x2.mdl",
+ dims = { S = 974, V = 1983.1 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x1x4", {
+ name = "1x1x4",
+ desc = "Dinghy",
+ model = "models/fueltank/fueltank_1x1x4.mdl",
+ dims = { S = 1777.4, V = 3995.1 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x2x1", {
+ name = "1x2x1",
+ desc = "Will keep a kart running all day.",
+ model = "models/fueltank/fueltank_1x2x1.mdl",
+ dims = { S = 995, V = 2062.5 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x2x2", {
+ name = "1x2x2",
+ desc = "Dinghy",
+ model = "models/fueltank/fueltank_1x2x2.mdl",
+ dims = { S = 1590.8, V = 4070.9 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x2x4", {
+ name = "1x2x4",
+ desc = "Outboard motor.",
+ model = "models/fueltank/fueltank_1x2x4.mdl",
+ dims = { S = 2796.6, V = 8119.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x4x1", {
+ name = "1x4x1",
+ desc = "Dinghy",
+ model = "models/fueltank/fueltank_1x4x1.mdl",
+ dims = { S = 1745.6, V = 3962 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x4x2", {
+ name = "1x4x2",
+ desc = "Clown car.",
+ model = "models/fueltank/fueltank_1x4x2.mdl",
+ dims = { S = 2753.9, V = 8018 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x4x4", {
+ name = "1x4x4",
+ desc = "Fuel pancake.",
+ model = "models/fueltank/fueltank_1x4x4.mdl",
+ dims = { S = 4761, V = 16030.4 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x6x1", {
+ name = "1x6x1",
+ desc = "Lawn tractors.",
+ model = "models/fueltank/fueltank_1x6x1.mdl",
+ dims = { S = 2535.3, V = 5973.1 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x6x2", {
+ name = "1x6x2",
+ desc = "Small tractor tank.",
+ model = "models/fueltank/fueltank_1x6x2.mdl",
+ dims = { S = 3954.1, V = 12100.3 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x6x4", {
+ name = "1x6x4",
+ desc = "Fuel. Will keep you going for awhile.",
+ model = "models/fueltank/fueltank_1x6x4.mdl",
+ dims = { S = 6743.3, V = 24109.4 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x8x1", {
+ name = "1x8x1",
+ desc = "Clown car.",
+ model = "models/fueltank/fueltank_1x8x1.mdl",
+ dims = { S = 3315.5, V = 7962.4 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x8x2", {
+ name = "1x8x2",
+ desc = "Gas stations? We don't need no stinking gas stations!",
+ model = "models/fueltank/fueltank_1x8x2.mdl",
+ dims = { S = 5113.7, V = 16026.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_1x8x4", {
+ name = "1x8x4",
+ desc = "Beep beep.",
+ model = "models/fueltank/fueltank_1x8x4.mdl",
+ dims = { S = 8696, V = 31871 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x2x1", {
+ name = "2x2x1",
+ desc = "Dinghy",
+ model = "models/fueltank/fueltank_2x2x1.mdl",
+ dims = { S = 1592.2, V = 4285.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x2x2", {
+ name = "2x2x2",
+ desc = "Clown car.",
+ model = "models/fueltank/fueltank_2x2x2.mdl",
+ dims = { S = 2360.4, V = 8212.9 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x2x4", {
+ name = "2x2x4",
+ desc = "Mini Cooper.",
+ model = "models/fueltank/fueltank_2x2x4.mdl",
+ dims = { S = 3988.6, V = 16362 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x4x1", {
+ name = "2x4x1",
+ desc = "Good bit of go-juice.",
+ model = "models/fueltank/fueltank_2x4x1.mdl",
+ dims = { S = 2808.8, V = 8628 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x4x2", {
+ name = "2x4x2",
+ desc = "Mini Cooper.",
+ model = "models/fueltank/fueltank_2x4x2.mdl",
+ dims = { S = 3996.1, V = 16761.4 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x4x4", {
+ name = "2x4x4",
+ desc = "Land boat.",
+ model = "models/fueltank/fueltank_2x4x4.mdl",
+ dims = { S = 6397.3, V = 32854.4 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x6x1", {
+ name = "2x6x1",
+ desc = "Conformal fuel tank, fits narrow spaces.",
+ model = "models/fueltank/fueltank_2x6x1.mdl",
+ dims = { S = 3861.4, V = 12389.9 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x6x2", {
+ name = "2x6x2",
+ desc = "Compact car.",
+ model = "models/fueltank/fueltank_2x6x2.mdl",
+ dims = { S = 5388, V = 24127.7 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x6x4", {
+ name = "2x6x4",
+ desc = "Sedan.",
+ model = "models/fueltank/fueltank_2x6x4.mdl",
+ dims = { S = 8485.6, V = 47537.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x8x1", {
+ name = "2x8x1",
+ desc = "Conformal fuel tank, fits into tight spaces",
+ model = "models/fueltank/fueltank_2x8x1.mdl",
+ dims = { S = 5094.5, V = 16831.8 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x8x2", {
+ name = "2x8x2",
+ desc = "Truck.",
+ model = "models/fueltank/fueltank_2x8x2.mdl",
+ dims = { S = 6980, V = 32275.9 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_2x8x4", {
+ name = "2x8x4",
+ desc = "With great capacity, comes great responsibili--VROOOOM",
+ model = "models/fueltank/fueltank_2x8x4.mdl",
+ dims = { S = 10898.2, V = 63976 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x4x1", {
+ name = "4x4x1",
+ desc = "Sedan.",
+ model = "models/fueltank/fueltank_4x4x1.mdl",
+ dims = { S = 4619.1, V = 16539.8 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x4x2", {
+ name = "4x4x2",
+ desc = "Land boat.",
+ model = "models/fueltank/fueltank_4x4x2.mdl",
+ dims = { S = 6071.4, V = 32165.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x4x4", {
+ name = "4x4x4",
+ desc = "Popular with arsonists.",
+ model = "models/fueltank/fueltank_4x4x4.mdl",
+ dims = { S = 9145.3, V = 62900.1 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x6x1", {
+ name = "4x6x1",
+ desc = "Conformal fuel tank, fits in tight spaces.",
+ model = "models/fueltank/fueltank_4x6x1.mdl",
+ dims = { S = 6553.6, V = 24918.6 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x6x2", {
+ name = "4x6x2",
+ desc = "Fire juice.",
+ model = "models/fueltank/fueltank_4x6x2.mdl",
+ dims = { S = 8425.3, V = 48581.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x6x4", {
+ name = "4x6x4",
+ desc = "Trees are gay anyway.",
+ model = "models/fueltank/fueltank_4x6x4.mdl",
+ dims = { S = 12200.6, V = 94640 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x8x1", {
+ name = "4x8x1",
+ desc = "Arson material.",
+ model = "models/fueltank/fueltank_4x8x1.mdl",
+ dims = { S = 8328.2, V = 32541.9 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x8x2", {
+ name = "4x8x2",
+ desc = "What's a gas station?",
+ model = "models/fueltank/fueltank_4x8x2.mdl",
+ dims = { S = 10419.5, V = 63167.1 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_4x8x4", {
+ name = "4x8x4",
+ desc = "\'MURRICA FUCKYEAH!",
+ model = "models/fueltank/fueltank_4x8x4.mdl",
+ dims = { S = 14993.3, V = 123693.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_6x6x1", {
+ name = "6x6x1",
+ desc = "Got gas?",
+ model = "models/fueltank/fueltank_6x6x1.mdl",
+ dims = { S = 9405.2, V = 37278.5 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_6x6x2", {
+ name = "6x6x2",
+ desc = "Drive across the desert without a fuck to give.",
+ model = "models/fueltank/fueltank_6x6x2.mdl",
+ dims = { S = 11514.5, V = 73606.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_6x6x4", {
+ name = "6x6x4",
+ desc = "May contain Mesozoic ghosts.",
+ model = "models/fueltank/fueltank_6x6x4.mdl",
+ dims = { S = 16028.8, V = 143269 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_6x8x1", {
+ name = "6x8x1",
+ desc = "Conformal fuel tank, does what all its friends do.",
+ model = "models/fueltank/fueltank_6x8x1.mdl",
+ dims = { S = 12131.1, V = 48480.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_6x8x2", {
+ name = "6x8x2",
+ desc = "Certified 100% dinosaur juice.",
+ model = "models/fueltank/fueltank_6x8x2.mdl",
+ dims = { S = 14403.8, V = 95065.5 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_6x8x4", {
+ name = "6x8x4",
+ desc = "Will last you a while.",
+ model = "models/fueltank/fueltank_6x8x4.mdl",
+ dims = { S = 19592.4, V = 187296.4 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_8x8x1", {
+ name = "8x8x1",
+ desc = "Sloshy sloshy!",
+ model = "models/fueltank/fueltank_8x8x1.mdl",
+ dims = { S = 15524.8, V = 64794.2 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_8x8x2", {
+ name = "8x8x2",
+ desc = "What's global warming?",
+ model = "models/fueltank/fueltank_8x8x2.mdl",
+ dims = { S = 18086.4, V = 125868.9 }
+} )
+
+ACF_DefineFuelTankSize( "Tank_8x8x4", {
+ name = "8x8x4",
+ desc = "Tank Tank.",
+ model = "models/fueltank/fueltank_8x8x4.mdl",
+ dims = { S = 23957.6, V = 246845.3 }
+} )
+
+ACF_DefineFuelTankSize( "Fuel_Drum", {
+ name = "Fuel Drum",
+ desc = "Tends to explode when shot.",
+ model = "models/props_c17/oildrum001_explosive.mdl",
+ dims = { S = 5128.9, V = 26794.4 }
+} )
+
+ACF_DefineFuelTankSize( "Jerry_Can", {
+ name = "Jerry Can",
+ desc = "Handy portable fuel container.",
+ model = "models/props_junk/gascan001a.mdl",
+ dims = { S = 1839.7, V = 4384.1 },
+} )
+
+ACF_DefineFuelTankSize( "Transport_Tank", {
+ name = "Transport Tank",
+ desc = "Disappointingly non-explosive.",
+ model = "models/props_wasteland/horizontalcoolingtank04.mdl",
+ dims = { S = 127505.5, V = 2102493.3 },
+ explosive = false,
+ nolinks = true
+} )
+
+ACF_DefineFuelTankSize( "Storage_Tank", {
+ name = "Storage Tank",
+ desc = "Disappointingly non-explosive.",
+ model = "models/props_wasteland/coolingtank02.mdl",
+ dims = { S = 144736.3, V = 2609960 },
+ explosive = false,
+ nolinks = true
+} )
diff --git a/lua/acf/shared/gearboxes/4-speed.lua b/lua/acf/shared/gearboxes/4-speed.lua
new file mode 100644
index 000000000..d75a05083
--- /dev/null
+++ b/lua/acf/shared/gearboxes/4-speed.lua
@@ -0,0 +1,315 @@
+
+-- 4-Speed gearboxes
+
+-- Weight
+local Gear4SW = 60
+local Gear4MW = 120
+local Gear4LW = 240
+local StWB = 0.75 --straight weight bonus mulitplier
+
+-- Torque Rating
+local Gear4ST = 540
+local Gear4MT = 1700
+local Gear4LT = 10000
+local StTB = 1.25 --straight torque bonus multiplier
+
+-- Inline
+
+ACF_DefineGearbox( "4Gear-L-S", {
+ name = "4-Speed, Inline, Small",
+ desc = "A small, and light 4 speed inline gearbox, with a somewhat limited max torque rating\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_s.mdl",
+ category = "4-Speed",
+ weight = Gear4SW,
+ switch = 0.15,
+ maxtq = Gear4ST,
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-L-M", {
+ name = "4-Speed, Inline, Medium",
+ desc = "A medium sized, 4 speed inline gearbox",
+ model = "models/engines/linear_m.mdl",
+ category = "4-Speed",
+ weight = Gear4MW,
+ switch = 0.2,
+ maxtq = Gear4MT,
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-L-L", {
+ name = "4-Speed, Inline, Large",
+ desc = "A large, heavy and sturdy 4 speed inline gearbox",
+ model = "models/engines/linear_l.mdl",
+ category = "4-Speed",
+ weight = Gear4LW,
+ switch = 0.3,
+ maxtq = Gear4LT,
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "4Gear-LD-S", {
+ name = "4-Speed, Inline, Small, Dual Clutch",
+ desc = "A small, and light 4 speed inline gearbox, with a somewhat limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_s.mdl",
+ category = "4-Speed",
+ weight = Gear4SW,
+ switch = 0.15,
+ maxtq = Gear4ST,
+ gears = 4,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-LD-M", {
+ name = "4-Speed, Inline, Medium, Dual Clutch",
+ desc = "A medium sized, 4 speed inline gearbox. The dual clutch allows you to apply power and brake each side independently",
+ model = "models/engines/linear_m.mdl",
+ category = "4-Speed",
+ weight = Gear4MW,
+ switch = 0.2,
+ maxtq = Gear4MT,
+ gears = 4,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-LD-L", {
+ name = "4-Speed, Inline, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 4 speed inline gearbox. The dual clutch allows you to apply power and brake each side independently",
+ model = "models/engines/linear_l.mdl",
+ category = "4-Speed",
+ weight = Gear4LW,
+ switch = 0.3,
+ maxtq = Gear4LT,
+ gears = 4,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "4Gear-T-S", {
+ name = "4-Speed, Transaxial, Small",
+ desc = "A small, and light 4 speed gearbox, with a somewhat limited max torque rating\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_s.mdl",
+ category = "4-Speed",
+ weight = Gear4SW,
+ switch = 0.15,
+ maxtq = Gear4ST,
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-T-M", {
+ name = "4-Speed, Transaxial, Medium",
+ desc = "A medium sized, 4 speed gearbox",
+ model = "models/engines/transaxial_m.mdl",
+ category = "4-Speed",
+ weight = Gear4MW,
+ switch = 0.2,
+ maxtq = Gear4MT,
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-T-L", {
+ name = "4-Speed, Transaxial, Large",
+ desc = "A large, heavy and sturdy 4 speed gearbox",
+ model = "models/engines/transaxial_l.mdl",
+ category = "4-Speed",
+ weight = Gear4LW,
+ switch = 0.3,
+ maxtq = Gear4LT,
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "4Gear-TD-S", {
+ name = "4-Speed, Transaxial, Small, Dual Clutch",
+ desc = "A small, and light 4 speed gearbox, with a somewhat limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_s.mdl",
+ category = "4-Speed",
+ weight = Gear4SW,
+ switch = 0.15,
+ maxtq = Gear4ST,
+ gears = 4,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-TD-M", {
+ name = "4-Speed, Transaxial, Medium, Dual Clutch",
+ desc = "A medium sized, 4 speed gearbox. The dual clutch allows you to apply power and brake each side independently",
+ model = "models/engines/transaxial_m.mdl",
+ category = "4-Speed",
+ weight = Gear4MW,
+ switch = 0.2,
+ maxtq = Gear4MT,
+ gears = 4,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-TD-L", {
+ name = "4-Speed, Transaxial, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 4 speed gearbox. The dual clutch allows you to apply power and brake each side independently",
+ model = "models/engines/transaxial_l.mdl",
+ category = "4-Speed",
+ weight = Gear4LW,
+ switch = 0.3,
+ maxtq = Gear4LT,
+ gears = 4,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Straight-through gearboxes
+
+ACF_DefineGearbox( "4Gear-ST-S", {
+ name = "4-Speed, Straight, Small",
+ desc = "A small straight-through gearbox",
+ model = "models/engines/t5small.mdl",
+ category = "4-Speed",
+ weight = math.floor(Gear4SW * StWB),
+ switch = 0.15,
+ maxtq = math.floor(Gear4ST * StTB),
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-ST-M", {
+ name = "4-Speed, Straight, Medium",
+ desc = "A medium sized, 4 speed straight-through gearbox.",
+ model = "models/engines/t5med.mdl",
+ category = "4-Speed",
+ weight = math.floor(Gear4MW * StWB),
+ switch = 0.2,
+ maxtq = math.floor(Gear4MT * StTB),
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "4Gear-ST-L", {
+ name = "4-Speed, Straight, Large",
+ desc = "A large sized, 4 speed straight-through gearbox.",
+ model = "models/engines/t5large.mdl",
+ category = "4-Speed",
+ weight = math.floor(Gear4LW * StWB),
+ switch = 0.3,
+ maxtq = math.floor(Gear4LT * StTB),
+ gears = 4,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
diff --git a/lua/acf/shared/gearboxes/6-speed.lua b/lua/acf/shared/gearboxes/6-speed.lua
new file mode 100644
index 000000000..e1b6641d1
--- /dev/null
+++ b/lua/acf/shared/gearboxes/6-speed.lua
@@ -0,0 +1,345 @@
+
+-- 6-Speed gearboxes
+
+-- Weight
+local Gear6SW = 80
+local Gear6MW = 160
+local Gear6LW = 320
+local StWB = 0.75 --straight weight bonus mulitplier
+
+-- Torque Rating
+local Gear6ST = 440
+local Gear6MT = 1360
+local Gear6LT = 10000
+local StTB = 1.25 --straight torque bonus multiplier
+
+-- Inline
+
+ACF_DefineGearbox( "6Gear-L-S", {
+ name = "6-Speed, Inline, Small",
+ desc = "A small and light 6 speed inline gearbox, with a limited max torque rating.",
+ model = "models/engines/linear_s.mdl",
+ category = "6-Speed",
+ weight = Gear6SW,
+ switch = 0.15,
+ maxtq = Gear6ST,
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-L-M", {
+ name = "6-Speed, Inline, Medium",
+ desc = "A medium duty 6 speed inline gearbox with a limited torque rating.",
+ model = "models/engines/linear_m.mdl",
+ category = "6-Speed",
+ weight = Gear6MW,
+ switch = 0.2,
+ maxtq = Gear6MT,
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-L-L", {
+ name = "6-Speed, Inline, Large",
+ desc = "Heavy duty 6 speed inline gearbox, however not as resilient as a 4 speed.",
+ model = "models/engines/linear_l.mdl",
+ category = "6-Speed",
+ weight = Gear6LW,
+ switch = 0.3,
+ maxtq = Gear6LT,
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "6Gear-LD-S", {
+ name = "6-Speed, Inline, Small, Dual Clutch",
+ desc = "A small and light 6 speed inline gearbox, with a limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_s.mdl",
+ category = "6-Speed",
+ weight = Gear6SW,
+ switch = 0.15,
+ maxtq = Gear6ST,
+ gears = 6,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-LD-M", {
+ name = "6-Speed, Inline, Medium, Dual Clutch",
+ desc = "A a medium duty 6 speed inline gearbox. The added gears reduce torque capacity substantially. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_m.mdl",
+ category = "6-Speed",
+ weight = Gear6MW,
+ switch = 0.2,
+ maxtq = Gear6MT,
+ gears = 6,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-LD-L", {
+ name = "6-Speed, Inline, Large, Dual Clutch",
+ desc = "Heavy duty 6 speed inline gearbox, however not as resilient as a 4 speed. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_l.mdl",
+ category = "6-Speed",
+ weight = Gear6LW,
+ switch = 0.3,
+ maxtq = Gear6LT,
+ gears = 6,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "6Gear-T-S", {
+ name = "6-Speed, Transaxial, Small",
+ desc = "A small and light 6 speed gearbox, with a limited max torque rating.",
+ model = "models/engines/transaxial_s.mdl",
+ category = "6-Speed",
+ weight = Gear6SW,
+ switch = 0.15,
+ maxtq = Gear6ST,
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-T-M", {
+ name = "6-Speed, Transaxial, Medium",
+ desc = "A medium duty 6 speed gearbox with a limited torque rating.",
+ model = "models/engines/transaxial_m.mdl",
+ category = "6-Speed",
+ weight = Gear6MW,
+ switch = 0.2,
+ maxtq = Gear6MT,
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-T-L", {
+ name = "6-Speed, Transaxial, Large",
+ desc = "Heavy duty 6 speed gearbox, however not as resilient as a 4 speed.",
+ model = "models/engines/transaxial_l.mdl",
+ category = "6-Speed",
+ weight = Gear6LW,
+ switch = 0.3,
+ maxtq = Gear6LT,
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "6Gear-TD-S", {
+ name = "6-Speed, Transaxial, Small, Dual Clutch",
+ desc = "A small and light 6 speed gearbox, with a limited max torque rating. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_s.mdl",
+ category = "6-Speed",
+ weight = Gear6SW,
+ switch = 0.15,
+ maxtq = Gear6ST,
+ gears = 6,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-TD-M", {
+ name = "6-Speed, Transaxial, Medium, Dual Clutch",
+ desc = "A a medium duty 6 speed gearbox. The added gears reduce torque capacity substantially. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_m.mdl",
+ category = "6-Speed",
+ weight = Gear6MW,
+ switch = 0.2,
+ maxtq = Gear6MT,
+ gears = 6,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-TD-L", {
+ name = "6-Speed, Transaxial, Large, Dual Clutch",
+ desc = "Heavy duty 6 speed gearbox, however not as resilient as a 4 speed. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_l.mdl",
+ category = "6-Speed",
+ weight = Gear6LW,
+ switch = 0.3,
+ maxtq = Gear6LT,
+ gears = 6,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Straight-through gearboxes
+
+ACF_DefineGearbox( "6Gear-ST-S", {
+ name = "6-Speed, Straight, Small",
+ desc = "A small and light 6 speed straight-through gearbox.",
+ model = "models/engines/t5small.mdl",
+ category = "6-Speed",
+ weight = math.floor(Gear6SW * StWB),
+ switch = 0.15,
+ maxtq = math.floor(Gear6ST * StTB),
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-ST-M", {
+ name = "6-Speed, Straight, Medium",
+ desc = "A medium 6 speed straight-through gearbox.",
+ model = "models/engines/t5med.mdl",
+ category = "6-Speed",
+ weight = math.floor(Gear6MW * StWB),
+ switch = 0.2,
+ maxtq = math.floor(Gear6MT * StTB),
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "6Gear-ST-L", {
+ name = "6-Speed, Straight, Large",
+ desc = "A large 6 speed straight-through gearbox.",
+ model = "models/engines/t5large.mdl",
+ category = "6-Speed",
+ weight = math.floor(Gear6LW * StWB),
+ switch = 0.3,
+ maxtq = math.floor(Gear6LT * StTB),
+ gears = 6,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
diff --git a/lua/acf/shared/gearboxes/8-speed.lua b/lua/acf/shared/gearboxes/8-speed.lua
new file mode 100644
index 000000000..2c4f65a94
--- /dev/null
+++ b/lua/acf/shared/gearboxes/8-speed.lua
@@ -0,0 +1,375 @@
+
+-- 8-Speed Gearboxes
+
+-- Weight
+local Gear8SW = 100
+local Gear8MW = 200
+local Gear8LW = 400
+local StWB = 0.75 --straight weight bonus mulitplier
+
+-- Torque Rating
+local Gear8ST = 340
+local Gear8MT = 1000
+local Gear8LT = 10000
+local StTB = 1.25 --straight torque bonus multiplier
+
+-- Inline
+
+ACF_DefineGearbox( "8Gear-L-S", {
+ name = "8-Speed, Inline, Small",
+ desc = "A small and light 8 speed gearbox.",
+ model = "models/engines/linear_s.mdl",
+ category = "8-Speed",
+ weight = Gear8SW,
+ switch = 0.15,
+ maxtq = Gear8ST,
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-L-M", {
+ name = "8-Speed, Inline, Medium",
+ desc = "A medium duty 8 speed gearbox..",
+ model = "models/engines/linear_m.mdl",
+ category = "8-Speed",
+ weight = Gear8MW,
+ switch = 0.2,
+ maxtq = Gear8MT,
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-L-L", {
+ name = "8-Speed, Inline, Large",
+ desc = "Heavy duty 8 speed gearbox, however rather heavy.",
+ model = "models/engines/linear_l.mdl",
+ category = "8-Speed",
+ weight = Gear8LW,
+ switch = 0.3,
+ maxtq = Gear8LT,
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "8Gear-LD-S", {
+ name = "8-Speed, Inline, Small, Dual Clutch",
+ desc = "A small and light 8 speed gearbox The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_s.mdl",
+ category = "8-Speed",
+ weight = Gear8SW,
+ switch = 0.15,
+ maxtq = Gear8ST,
+ gears = 8,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-LD-M", {
+ name = "8-Speed, Inline, Medium, Dual Clutch",
+ desc = "A a medium duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_m.mdl",
+ category = "8-Speed",
+ weight = Gear8MW,
+ switch = 0.2,
+ maxtq = Gear8MT,
+ gears = 8,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-LD-L", {
+ name = "8-Speed, Inline, Large, Dual Clutch",
+ desc = "Heavy duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/linear_l.mdl",
+ category = "8-Speed",
+ weight = Gear8LW,
+ switch = 0.3,
+ maxtq = Gear8LT,
+ gears = 8,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "8Gear-T-S", {
+ name = "8-Speed, Transaxial, Small",
+ desc = "A small and light 8 speed gearbox..",
+ model = "models/engines/transaxial_s.mdl",
+ category = "8-Speed",
+ weight = Gear8SW,
+ switch = 0.15,
+ maxtq = Gear8ST,
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-T-M", {
+ name = "8-Speed, Transaxial, Medium",
+ desc = "A medium duty 8 speed gearbox..",
+ model = "models/engines/transaxial_m.mdl",
+ category = "8-Speed",
+ weight = Gear8MW,
+ switch = 0.2,
+ maxtq = Gear8MT,
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-T-L", {
+ name = "8-Speed, Transaxial, Large",
+ desc = "Heavy duty 8 speed gearbox, however rather heavy.",
+ model = "models/engines/transaxial_l.mdl",
+ category = "8-Speed",
+ weight = Gear8LW,
+ switch = 0.3,
+ maxtq = Gear8LT,
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "8Gear-TD-S", {
+ name = "8-Speed, Transaxial, Small, Dual Clutch",
+ desc = "A small and light 8 speed gearbox The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_s.mdl",
+ category = "8-Speed",
+ weight = Gear8SW,
+ switch = 0.15,
+ maxtq = Gear8ST,
+ gears = 8,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-TD-M", {
+ name = "8-Speed, Transaxial, Medium, Dual Clutch",
+ desc = "A a medium duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_m.mdl",
+ category = "8-Speed",
+ weight = Gear8MW,
+ switch = 0.2,
+ maxtq = Gear8MT,
+ gears = 8,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-TD-L", {
+ name = "8-Speed, Transaxial, Large, Dual Clutch",
+ desc = "Heavy duty 8 speed gearbox. The dual clutch allows you to apply power and brake each side independently\n\nThe Final Drive slider is a multiplier applied to all the other gear ratios",
+ model = "models/engines/transaxial_l.mdl",
+ category = "8-Speed",
+ weight = Gear8LW,
+ switch = 0.3,
+ maxtq = Gear8LT,
+ gears = 8,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Straight-through gearboxes
+
+ACF_DefineGearbox( "8Gear-ST-S", {
+ name = "8-Speed, Straight, Small",
+ desc = "A small and light 8 speed straight-through gearbox.",
+ model = "models/engines/t5small.mdl",
+ category = "8-Speed",
+ weight = math.floor(Gear8SW * StWB),
+ switch = 0.15,
+ maxtq = math.floor(Gear8ST * StTB),
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = 0.8,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-ST-M", {
+ name = "8-Speed, Straight, Medium",
+ desc = "A medium 8 speed straight-through gearbox.",
+ model = "models/engines/t5med.mdl",
+ category = "8-Speed",
+ weight = math.floor(Gear8MW * StWB),
+ switch = 0.2,
+ maxtq = math.floor(Gear8MT * StTB),
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "8Gear-ST-L", {
+ name = "8-Speed, Straight, Large",
+ desc = "A large 8 speed straight-through gearbox.",
+ model = "models/engines/t5large.mdl",
+ category = "8-Speed",
+ weight = math.floor(Gear8LW * StWB),
+ switch = 0.3,
+ maxtq = math.floor(Gear8LT * StTB),
+ gears = 8,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ 8 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
diff --git a/lua/acf/shared/gearboxes/automatic.lua b/lua/acf/shared/gearboxes/automatic.lua
new file mode 100644
index 000000000..71b3ff624
--- /dev/null
+++ b/lua/acf/shared/gearboxes/automatic.lua
@@ -0,0 +1,1085 @@
+
+-- Automatic Gearboxes
+
+-- Weight
+local wmul = 1.5
+local Gear3SW = 60 * wmul
+local Gear3MW = 120 * wmul
+local Gear3LW = 240 * wmul
+
+local Gear5SW = 80 * wmul
+local Gear5MW = 160 * wmul
+local Gear5LW = 320 * wmul
+
+local Gear7SW = 100 * wmul
+local Gear7MW = 200 * wmul
+local Gear7LW = 400 * wmul
+
+-- Torque Rating
+local Gear3ST = 675
+local Gear3MT = 2125
+local Gear3LT = 10000
+
+local Gear5ST = 550
+local Gear5MT = 1700
+local Gear5LT = 10000
+
+local Gear7ST = 425
+local Gear7MT = 1250
+local Gear7LT = 10000
+
+-- Straight through bonuses
+local StWB = 0.75 --straight weight bonus mulitplier
+local StTB = 1.25 --straight torque bonus multiplier
+
+-- Shift Time
+local ShiftS = 0.25
+local ShiftM = 0.35
+local ShiftL = 0.5
+
+local blurb = "\n\nAutomatics are controlled by shifting into either forward or reverse drive. In forward drive, the automatic will choose the appropriate gearing based the upshift speed setting for each gear."
+blurb = blurb .. " For climbing inclines, automatics have an input to prevent upshifts. There's also an input for adjusting the shiftpoints, if for example you're driving with less throttle and want to shift earlier."
+blurb = blurb .. " However, automatics are significantly heavier than their manual counterparts, and lose a bit of output torque due to inefficiency."
+--hold gear, shift scale, less efficient
+-- 3 Speed
+-- Inline
+
+ACF_DefineGearbox( "3Gear-A-L-S", {
+ name = "3-Speed Auto, Inline, Small",
+ desc = "A small, and light 3 speed automatic inline gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/linear_s.mdl",
+ category = "Automatic",
+ weight = Gear3SW,
+ switch = ShiftS,
+ maxtq = Gear3ST,
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1, --reverse
+ [ -1 ] = 0.5 --final drive
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-L-M", {
+ name = "3-Speed Auto, Inline, Medium",
+ desc = "A medium sized, 3 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_m.mdl",
+ category = "Automatic",
+ weight = Gear3MW,
+ switch = ShiftM,
+ maxtq = Gear3MT,
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-L-L", {
+ name = "3-Speed Auto, Inline, Large",
+ desc = "A large, heavy and sturdy 3 speed inline gearbox"..blurb,
+ model = "models/engines/linear_l.mdl",
+ category = "Automatic",
+ weight = Gear3LW,
+ switch = ShiftL,
+ maxtq = Gear3LT,
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "3Gear-A-LD-S", {
+ name = "3-Speed Auto, Inline, Small, Dual Clutch",
+ desc = "A small, and light 3 speed automatic inline gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/linear_s.mdl",
+ category = "Automatic",
+ weight = Gear3SW,
+ switch = ShiftS,
+ maxtq = Gear3ST,
+ auto = true,
+ doubleclutch = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-LD-M", {
+ name = "3-Speed Auto, Inline, Medium, Dual Clutch",
+ desc = "A medium sized, 3 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_m.mdl",
+ category = "Automatic",
+ weight = Gear3MW,
+ switch = ShiftM,
+ maxtq = Gear3MT,
+ auto = true,
+ doubleclutch = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-LD-L", {
+ name = "3-Speed Auto, Inline, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 3 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_l.mdl",
+ category = "Automatic",
+ weight = Gear3LW,
+ switch = ShiftL,
+ maxtq = Gear3LT,
+ auto = true,
+ doubleclutch = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "3Gear-A-T-S", {
+ name = "3-Speed Auto, Transaxial, Small",
+ desc = "A small, and light 3 speed automatic gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/transaxial_s.mdl",
+ category = "Automatic",
+ weight = Gear3SW,
+ switch = ShiftS,
+ maxtq = Gear3ST,
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-T-M", {
+ name = "3-Speed Auto, Transaxial, Medium",
+ desc = "A medium sized, 3 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_m.mdl",
+ category = "Automatic",
+ weight = Gear3MW,
+ switch = ShiftM,
+ maxtq = Gear3MT,
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-T-L", {
+ name = "3-Speed Auto, Transaxial, Large",
+ desc = "A large, heavy and sturdy 3 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_l.mdl",
+ category = "Automatic",
+ weight = Gear3LW,
+ switch = ShiftL,
+ maxtq = Gear3LT,
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "3Gear-A-TD-S", {
+ name = "3-Speed Auto, Transaxial, Small, Dual Clutch",
+ desc = "A small, and light 3 speed automatic gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/transaxial_s.mdl",
+ category = "Automatic",
+ weight = Gear3SW,
+ switch = ShiftS,
+ maxtq = Gear3ST,
+ auto = true,
+ doubleclutch = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-TD-M", {
+ name = "3-Speed Auto, Transaxial, Medium, Dual Clutch",
+ desc = "A medium sized, 3 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_m.mdl",
+ category = "Automatic",
+ weight = Gear3MW,
+ switch = ShiftM,
+ maxtq = Gear3MT,
+ auto = true,
+ doubleclutch = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-TD-L", {
+ name = "3-Speed Auto, Transaxial, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 3 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_l.mdl",
+ category = "Automatic",
+ weight = Gear3LW,
+ switch = ShiftL,
+ maxtq = Gear3LT,
+ auto = true,
+ doubleclutch = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+-- Straight-through gearboxes
+
+ACF_DefineGearbox( "3Gear-A-ST-S", {
+ name = "3-Speed Auto, Straight, Small",
+ desc = "A small straight-through automatic gearbox"..blurb,
+ model = "models/engines/t5small.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear3SW * StWB),
+ switch = ShiftS,
+ maxtq = math.floor(Gear3ST * StTB),
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 1
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-ST-M", {
+ name = "3-Speed Auto, Straight, Medium",
+ desc = "A medium sized, 3 speed automatic straight-through gearbox."..blurb,
+ model = "models/engines/t5med.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear3MW * StWB),
+ switch = ShiftM,
+ maxtq = math.floor(Gear3MT * StTB),
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "3Gear-A-ST-L", {
+ name = "3-Speed Auto, Straight, Large",
+ desc = "A large sized, 3 speed automatic straight-through gearbox."..blurb,
+ model = "models/engines/t5large.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear3LW * StWB),
+ switch = ShiftL,
+ maxtq = math.floor(Gear3LT * StTB),
+ auto = true,
+ gears = 3,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+
+-- 5 Speed
+-- Inline
+
+ACF_DefineGearbox( "5Gear-A-L-S", {
+ name = "5-Speed Auto, Inline, Small",
+ desc = "A small, and light 5 speed automatic inline gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/linear_s.mdl",
+ category = "Automatic",
+ weight = Gear5SW,
+ switch = ShiftS,
+ maxtq = Gear5ST,
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-L-M", {
+ name = "5-Speed Auto, Inline, Medium",
+ desc = "A medium sized, 5 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_m.mdl",
+ category = "Automatic",
+ weight = Gear5MW,
+ switch = ShiftM,
+ maxtq = Gear5MT,
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-L-L", {
+ name = "5-Speed Auto, Inline, Large",
+ desc = "A large, heavy and sturdy 5 speed inline gearbox"..blurb,
+ model = "models/engines/linear_l.mdl",
+ category = "Automatic",
+ weight = Gear5LW,
+ switch = ShiftL,
+ maxtq = Gear5LT,
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "5Gear-A-LD-S", {
+ name = "5-Speed Auto, Inline, Small, Dual Clutch",
+ desc = "A small, and light 5 speed automatic inline gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/linear_s.mdl",
+ category = "Automatic",
+ weight = Gear5SW,
+ switch = ShiftS,
+ maxtq = Gear5ST,
+ auto = true,
+ doubleclutch = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-LD-M", {
+ name = "5-Speed Auto, Inline, Medium, Dual Clutch",
+ desc = "A medium sized, 5 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_m.mdl",
+ category = "Automatic",
+ weight = Gear5MW,
+ switch = ShiftM,
+ maxtq = Gear5MT,
+ auto = true,
+ doubleclutch = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-LD-L", {
+ name = "5-Speed Auto, Inline, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 5 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_l.mdl",
+ category = "Automatic",
+ weight = Gear5LW,
+ switch = ShiftL,
+ maxtq = Gear5LT,
+ auto = true,
+ doubleclutch = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "5Gear-A-T-S", {
+ name = "5-Speed Auto, Transaxial, Small",
+ desc = "A small, and light 5 speed automatic gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/transaxial_s.mdl",
+ category = "Automatic",
+ weight = Gear5SW,
+ switch = ShiftS,
+ maxtq = Gear5ST,
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-T-M", {
+ name = "5-Speed Auto, Transaxial, Medium",
+ desc = "A medium sized, 5 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_m.mdl",
+ category = "Automatic",
+ weight = Gear5MW,
+ switch = ShiftM,
+ maxtq = Gear5MT,
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-T-L", {
+ name = "5-Speed Auto, Transaxial, Large",
+ desc = "A large, heavy and sturdy 5 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_l.mdl",
+ category = "Automatic",
+ weight = Gear5LW,
+ switch = ShiftL,
+ maxtq = Gear5LT,
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "5Gear-A-TD-S", {
+ name = "5-Speed Auto, Transaxial, Small, Dual Clutch",
+ desc = "A small, and light 5 speed automatic gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/transaxial_s.mdl",
+ category = "Automatic",
+ weight = Gear5SW,
+ switch = ShiftS,
+ maxtq = Gear5ST,
+ auto = true,
+ doubleclutch = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-TD-M", {
+ name = "5-Speed Auto, Transaxial, Medium, Dual Clutch",
+ desc = "A medium sized, 5 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_m.mdl",
+ category = "Automatic",
+ weight = Gear5MW,
+ switch = ShiftM,
+ maxtq = Gear5MT,
+ auto = true,
+ doubleclutch = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-TD-L", {
+ name = "5-Speed Auto, Transaxial, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 5 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_l.mdl",
+ category = "Automatic",
+ weight = Gear5LW,
+ switch = ShiftL,
+ maxtq = Gear5LT,
+ auto = true,
+ doubleclutch = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Straight-through gearboxes
+
+ACF_DefineGearbox( "5Gear-A-ST-S", {
+ name = "5-Speed Auto, Straight, Small",
+ desc = "A small straight-through automatic gearbox"..blurb,
+ model = "models/engines/t5small.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear5SW * StWB),
+ switch = ShiftS,
+ maxtq = math.floor(Gear5ST * StTB),
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-ST-M", {
+ name = "5-Speed Auto, Straight, Medium",
+ desc = "A medium sized, 5 speed automatic straight-through gearbox."..blurb,
+ model = "models/engines/t5med.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear5MW * StWB),
+ switch = ShiftM,
+ maxtq = math.floor(Gear5MT * StTB),
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "5Gear-A-ST-L", {
+ name = "5-Speed Auto, Straight, Large",
+ desc = "A large sized, 5 speed automatic straight-through gearbox."..blurb,
+ model = "models/engines/t5large.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear5LW * StWB),
+ switch = ShiftL,
+ maxtq = math.floor(Gear5LT * StTB),
+ auto = true,
+ gears = 5,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+
+-- 7 Speed
+-- Inline
+
+ACF_DefineGearbox( "7Gear-A-L-S", {
+ name = "7-Speed Auto, Inline, Small",
+ desc = "A small, and light 7 speed automatic inline gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/linear_s.mdl",
+ category = "Automatic",
+ weight = Gear7SW,
+ switch = ShiftS,
+ maxtq = Gear7ST,
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-L-M", {
+ name = "7-Speed Auto, Inline, Medium",
+ desc = "A medium sized, 7 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_m.mdl",
+ category = "Automatic",
+ weight = Gear7MW,
+ switch = ShiftM,
+ maxtq = Gear7MT,
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-L-L", {
+ name = "7-Speed Auto, Inline, Large",
+ desc = "A large, heavy and sturdy 7 speed inline gearbox"..blurb,
+ model = "models/engines/linear_l.mdl",
+ category = "Automatic",
+ weight = Gear7LW,
+ switch = ShiftL,
+ maxtq = Gear7LT,
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "7Gear-A-LD-S", {
+ name = "7-Speed Auto, Inline, Small, Dual Clutch",
+ desc = "A small, and light 7 speed automatic inline gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/linear_s.mdl",
+ category = "Automatic",
+ weight = Gear7SW,
+ switch = ShiftS,
+ maxtq = Gear7ST,
+ auto = true,
+ doubleclutch = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-LD-M", {
+ name = "7-Speed Auto, Inline, Medium, Dual Clutch",
+ desc = "A medium sized, 7 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_m.mdl",
+ category = "Automatic",
+ weight = Gear7MW,
+ switch = ShiftM,
+ maxtq = Gear7MT,
+ auto = true,
+ doubleclutch = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-LD-L", {
+ name = "7-Speed Auto, Inline, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 7 speed automatic inline gearbox"..blurb,
+ model = "models/engines/linear_l.mdl",
+ category = "Automatic",
+ weight = Gear7LW,
+ switch = ShiftL,
+ maxtq = Gear7LT,
+ auto = true,
+ doubleclutch = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "7Gear-A-T-S", {
+ name = "7-Speed Auto, Transaxial, Small",
+ desc = "A small, and light 7 speed automatic gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/transaxial_s.mdl",
+ category = "Automatic",
+ weight = Gear7SW,
+ switch = ShiftS,
+ maxtq = Gear7ST,
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-T-M", {
+ name = "7-Speed Auto, Transaxial, Medium",
+ desc = "A medium sized, 7 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_m.mdl",
+ category = "Automatic",
+ weight = Gear7MW,
+ switch = ShiftM,
+ maxtq = Gear7MT,
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-T-L", {
+ name = "7-Speed Auto, Transaxial, Large",
+ desc = "A large, heavy and sturdy 7 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_l.mdl",
+ category = "Automatic",
+ weight = Gear7LW,
+ switch = ShiftL,
+ maxtq = Gear7LT,
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "7Gear-A-TD-S", {
+ name = "7-Speed Auto, Transaxial, Small, Dual Clutch",
+ desc = "A small, and light 7 speed automatic gearbox, with a somewhat limited max torque rating"..blurb,
+ model = "models/engines/transaxial_s.mdl",
+ category = "Automatic",
+ weight = Gear7SW,
+ switch = ShiftS,
+ maxtq = Gear7ST,
+ auto = true,
+ doubleclutch = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-TD-M", {
+ name = "7-Speed Auto, Transaxial, Medium, Dual Clutch",
+ desc = "A medium sized, 7 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_m.mdl",
+ category = "Automatic",
+ weight = Gear7MW,
+ switch = ShiftM,
+ maxtq = Gear7MT,
+ auto = true,
+ doubleclutch = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-TD-L", {
+ name = "7-Speed Auto, Transaxial, Large, Dual Clutch",
+ desc = "A large, heavy and sturdy 7 speed automatic gearbox"..blurb,
+ model = "models/engines/transaxial_l.mdl",
+ category = "Automatic",
+ weight = Gear7LW,
+ switch = ShiftL,
+ maxtq = Gear7LT,
+ auto = true,
+ doubleclutch = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+-- Straight-through gearboxes
+
+ACF_DefineGearbox( "7Gear-A-ST-S", {
+ name = "7-Speed Auto, Straight, Small",
+ desc = "A small straight-through automatic gearbox"..blurb,
+ model = "models/engines/t5small.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear7SW * StWB),
+ switch = ShiftS,
+ maxtq = math.floor(Gear7ST * StTB),
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-ST-M", {
+ name = "7-Speed Auto, Straight, Medium",
+ desc = "A medium sized, 7 speed automatic straight-through gearbox."..blurb,
+ model = "models/engines/t5med.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear7MW * StWB),
+ switch = ShiftM,
+ maxtq = math.floor(Gear7MT * StTB),
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "7Gear-A-ST-L", {
+ name = "7-Speed Auto, Straight, Large",
+ desc = "A large sized, 7 speed automatic straight-through gearbox."..blurb,
+ model = "models/engines/t5large.mdl",
+ category = "Automatic",
+ weight = math.floor(Gear7LW * StWB),
+ switch = ShiftL,
+ maxtq = math.floor(Gear7LT * StTB),
+ auto = true,
+ gears = 7,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.1,
+ [ 2 ] = 0.2,
+ [ 3 ] = 0.3,
+ [ 4 ] = 0.4,
+ [ 5 ] = 0.5,
+ [ 6 ] = 0.6,
+ [ 7 ] = 0.7,
+ [ -2 ] = -0.1,
+ [ -1 ] = 0.5
+ }
+} )
diff --git a/lua/acf/shared/gearboxes/clutch.lua b/lua/acf/shared/gearboxes/clutch.lua
new file mode 100644
index 000000000..a42f8e2eb
--- /dev/null
+++ b/lua/acf/shared/gearboxes/clutch.lua
@@ -0,0 +1,83 @@
+
+-- Clutch
+
+-- Weight
+local CTW = 2
+local CSW = 5
+local CMW = 10
+local CLW = 20
+
+-- Torque Rating
+local CTT = 75
+local CST = 650
+local CMT = 1400
+local CLT = 8000
+
+-- general description
+local CDesc = "A standalone clutch for when a full size gearbox is unnecessary or too long."
+
+-- Straight-through
+
+ACF_DefineGearbox( "Clutch-S-T", {
+ name = "Clutch, Straight, Tiny",
+ desc = CDesc,
+ model = "models/engines/flywheelclutcht.mdl",
+ category = "Clutch",
+ weight = CTW,
+ parentable = true,
+ switch = 0.1,
+ maxtq = CTT,
+ gears = 0,
+ geartable = {
+ [ 0 ] = 1,
+ [ -1 ] = 1
+ }
+} )
+
+ACF_DefineGearbox( "Clutch-S-S", {
+ name = "Clutch, Straight, Small",
+ desc = CDesc,
+ model = "models/engines/flywheelclutchs.mdl",
+ category = "Clutch",
+ weight = CSW,
+ parentable = true,
+ switch = 0.15,
+ maxtq = CST,
+ gears = 0,
+ geartable = {
+ [ 0 ] = 1,
+ [ -1 ] = 1
+ }
+} )
+
+ACF_DefineGearbox( "Clutch-S-M", {
+ name = "Clutch, Straight, Medium",
+ desc = CDesc,
+ model = "models/engines/flywheelclutchm.mdl",
+ category = "Clutch",
+ weight = CMW,
+ parentable = true,
+ switch = 0.2,
+ maxtq = CMT,
+ gears = 0,
+ geartable = {
+ [ 0 ] = 1,
+ [ -1 ] = 1
+ }
+} )
+
+ACF_DefineGearbox( "Clutch-S-L", {
+ name = "Clutch, Straight, Large",
+ desc = CDesc,
+ model = "models/engines/flywheelclutchb.mdl",
+ category = "Clutch",
+ weight = CLW,
+ parentable = true,
+ switch = 0.3,
+ maxtq = CLT,
+ gears = 0,
+ geartable = {
+ [ 0 ] = 1,
+ [ -1 ] = 1
+ }
+} )
diff --git a/lua/acf/shared/gearboxes/cvt.lua b/lua/acf/shared/gearboxes/cvt.lua
new file mode 100644
index 000000000..b1842d3ef
--- /dev/null
+++ b/lua/acf/shared/gearboxes/cvt.lua
@@ -0,0 +1,333 @@
+
+-- CVT (continuously variable transmission)
+
+-- Weight
+local GearCVTSW = 65
+local GearCVTMW = 180
+local GearCVTLW = 500
+local StWB = 0.75 --straight weight bonus mulitplier
+
+-- Torque Rating
+local GearCVTST = 175
+local GearCVTMT = 650
+local GearCVTLT = 6000
+local StTB = 1.25 --straight torque bonus multiplier
+
+-- general description
+local CVTDesc = "\n\nA CVT will adjust the ratio its first gear to keep an engine within a target rpm range, allowing constant peak performance. However, this comes at the cost of increased weight and limited torque ratings."
+
+-- Inline
+
+ACF_DefineGearbox( "CVT-L-S", {
+ name = "CVT, Inline, Small",
+ desc = "A light duty inline CVT."..CVTDesc,
+ model = "models/engines/linear_s.mdl",
+ category = "CVT",
+ weight = GearCVTSW,
+ switch = 0.15,
+ maxtq = GearCVTST,
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-L-M", {
+ name = "CVT, Inline, Medium",
+ desc = "A medium inline CVT."..CVTDesc,
+ model = "models/engines/linear_m.mdl",
+ category = "CVT",
+ weight = GearCVTMW,
+ switch = 0.2,
+ maxtq = GearCVTMT,
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-L-L", {
+ name = "CVT, Inline, Large",
+ desc = "A massive inline CVT designed for high torque applications."..CVTDesc,
+ model = "models/engines/linear_l.mdl",
+ category = "CVT",
+ weight = GearCVTLW,
+ switch = 0.3,
+ maxtq = GearCVTLT,
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "CVT-LD-S", {
+ name = "CVT, Inline, Small, Dual Clutch",
+ desc = "A light duty inline CVT. The dual clutch allows you to apply power and brake each side independently."..CVTDesc,
+ model = "models/engines/linear_s.mdl",
+ category = "CVT",
+ weight = GearCVTSW,
+ switch = 0.15,
+ maxtq = GearCVTST,
+ gears = 2,
+ doubleclutch = true,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-LD-M", {
+ name = "CVT, Inline, Medium, Dual Clutch",
+ desc = "A medium inline CVT. The dual clutch allows you to apply power and brake each side independently."..CVTDesc,
+ model = "models/engines/linear_m.mdl",
+ category = "CVT",
+ weight = GearCVTMW,
+ switch = 0.2,
+ maxtq = GearCVTMT,
+ gears = 2,
+ doubleclutch = true,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-LD-L", {
+ name = "CVT, Inline, Large, Dual Clutch",
+ desc = "A massive inline CVT designed for high torque applications. The dual clutch allows you to apply power and brake each side independently."..CVTDesc,
+ model = "models/engines/linear_l.mdl",
+ category = "CVT",
+ weight = GearCVTLW,
+ switch = 0.3,
+ maxtq = GearCVTLT,
+ gears = 2,
+ doubleclutch = true,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "CVT-T-S", {
+ name = "CVT, Transaxial, Small",
+ desc = "A light duty CVT."..CVTDesc,
+ model = "models/engines/transaxial_s.mdl",
+ category = "CVT",
+ weight = GearCVTSW,
+ switch = 0.15,
+ maxtq = GearCVTST,
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-T-M", {
+ name = "CVT, Transaxial, Medium",
+ desc = "A medium CVT."..CVTDesc,
+ model = "models/engines/transaxial_m.mdl",
+ category = "CVT",
+ weight = GearCVTMW,
+ switch = 0.2,
+ maxtq = GearCVTMT,
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-T-L", {
+ name = "CVT, Transaxial, Large",
+ desc = "A massive CVT designed for high torque applications."..CVTDesc,
+ model = "models/engines/transaxial_l.mdl",
+ category = "CVT",
+ weight = GearCVTLW,
+ switch = 0.3,
+ maxtq = GearCVTLT,
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "CVT-TD-S", {
+ name = "CVT, Transaxial, Small, Dual Clutch",
+ desc = "A light duty CVT. The dual clutch allows you to apply power and brake each side independently."..CVTDesc,
+ model = "models/engines/transaxial_s.mdl",
+ category = "CVT",
+ weight = GearCVTSW,
+ switch = 0.15,
+ maxtq = GearCVTST,
+ gears = 2,
+ doubleclutch = true,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-TD-M", {
+ name = "CVT, Transaxial, Medium, Dual Clutch",
+ desc = "A medium CVT. The dual clutch allows you to apply power and brake each side independently."..CVTDesc,
+ model = "models/engines/transaxial_m.mdl",
+ category = "CVT",
+ weight = GearCVTMW,
+ switch = 0.2,
+ maxtq = GearCVTMT,
+ gears = 2,
+ doubleclutch = true,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-TD-L", {
+ name = "CVT, Transaxial, Large, Dual Clutch",
+ desc = "A massive CVT designed for high torque applications. The dual clutch allows you to apply power and brake each side independently."..CVTDesc,
+ model = "models/engines/transaxial_l.mdl",
+ category = "CVT",
+ weight = GearCVTLW,
+ switch = 0.3,
+ maxtq = GearCVTLT,
+ gears = 2,
+ doubleclutch = true,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+-- Straight-through gearboxes
+
+ACF_DefineGearbox( "CVT-ST-S", {
+ name = "CVT, Straight, Small",
+ desc = "A light duty straight-through CVT."..CVTDesc,
+ model = "models/engines/t5small.mdl",
+ category = "CVT",
+ weight = math.floor(GearCVTSW * StWB),
+ switch = 0.15,
+ maxtq = math.floor(GearCVTST * StTB),
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-ST-M", {
+ name = "CVT, Straight, Medium",
+ desc = "A medium straight-through CVT."..CVTDesc,
+ model = "models/engines/t5med.mdl",
+ category = "CVT",
+ weight = math.floor(GearCVTMW * StWB),
+ switch = 0.2,
+ maxtq = math.floor(GearCVTMT * StTB),
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
+
+ACF_DefineGearbox( "CVT-ST-L", {
+ name = "CVT, Straight, Large",
+ desc = "A massive straight-through CVT designed for high torque applications."..CVTDesc,
+ model = "models/engines/t5large.mdl",
+ category = "CVT",
+ weight = math.floor(GearCVTLW * StWB),
+ switch = 0.3,
+ maxtq = math.floor(GearCVTLT * StTB),
+ gears = 2,
+ cvt = true,
+ geartable = {
+ [-3] = 3000, --target min rpm
+ [-2] = 5000, --target max rpm
+ [-1] = 1, --final drive
+ [ 0 ] = 0,
+ [ 1 ] = 0,
+ [ 2 ] = -0.1
+ }
+} )
diff --git a/lua/acf/shared/gearboxes/differential.lua b/lua/acf/shared/gearboxes/differential.lua
new file mode 100644
index 000000000..022c5739c
--- /dev/null
+++ b/lua/acf/shared/gearboxes/differential.lua
@@ -0,0 +1,224 @@
+
+-- Differentials
+
+local Gear1SW = 10
+local Gear1MW = 20
+local Gear1LW = 40
+
+-- Inline
+
+ACF_DefineGearbox( "1Gear-L-S", {
+ name = "Differential, Inline, Small",
+ desc = "Small differential, used to connect power from gearbox to wheels",
+ model = "models/engines/linear_s.mdl",
+ category = "Differential",
+ weight = Gear1SW,
+ parentable = true,
+ switch = 0.3,
+ maxtq = 25000,
+ gears = 1,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-L-M", {
+ name = "Differential, Inline, Medium",
+ desc = "Medium duty differential",
+ model = "models/engines/linear_m.mdl",
+ category = "Differential",
+ weight = Gear1MW,
+ parentable = true,
+ switch = 0.4,
+ maxtq = 50000,
+ gears = 1,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-L-L", {
+ name = "Differential, Inline, Large",
+ desc = "Heavy duty differential, for the heaviest of engines",
+ model = "models/engines/linear_l.mdl",
+ category = "Differential",
+ weight = Gear1LW,
+ parentable = true,
+ switch = 0.6,
+ maxtq = 100000,
+ gears = 1,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 1
+ }
+} )
+
+-- Inline Dual Clutch
+
+ACF_DefineGearbox( "1Gear-LD-S", {
+ name = "Differential, Inline, Small, Dual Clutch",
+ desc = "Small differential, used to connect power from gearbox to wheels",
+ model = "models/engines/linear_s.mdl",
+ category = "Differential",
+ weight = Gear1SW,
+ parentable = true,
+ switch = 0.3,
+ maxtq = 25000,
+ gears = 1,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-LD-M", {
+ name = "Differential, Inline, Medium, Dual Clutch",
+ desc = "Medium duty differential",
+ model = "models/engines/linear_m.mdl",
+ category = "Differential",
+ weight = Gear1MW,
+ parentable = true,
+ switch = 0.4,
+ maxtq = 50000,
+ gears = 1,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-LD-L", {
+ name = "Differential, Inline, Large, Dual Clutch",
+ desc = "Heavy duty differential, for the heaviest of engines",
+ model = "models/engines/linear_l.mdl",
+ category = "Differential",
+ weight = Gear1LW,
+ parentable = true,
+ switch = 0.6,
+ maxtq = 100000,
+ gears = 1,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "1Gear-T-S", {
+ name = "Differential, Small",
+ desc = "Small differential, used to connect power from gearbox to wheels",
+ model = "models/engines/transaxial_s.mdl",
+ category = "Differential",
+ weight = Gear1SW,
+ parentable = true,
+ switch = 0.3,
+ maxtq = 25000,
+ gears = 1,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-T-M", {
+ name = "Differential, Medium",
+ desc = "Medium duty differential",
+ model = "models/engines/transaxial_m.mdl",
+ category = "Differential",
+ weight = Gear1MW,
+ parentable = true,
+ switch = 0.4,
+ maxtq = 50000,
+ gears = 1,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-T-L", {
+ name = "Differential, Large",
+ desc = "Heavy duty differential, for the heaviest of engines",
+ model = "models/engines/transaxial_l.mdl",
+ category = "Differential",
+ parentable = true,
+ weight = Gear1LW,
+ switch = 0.6,
+ maxtq = 100000,
+ gears = 1,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial Dual Clutch
+
+ACF_DefineGearbox( "1Gear-TD-S", {
+ name = "Differential, Small, Dual Clutch",
+ desc = "Small differential, used to connect power from gearbox to wheels",
+ model = "models/engines/transaxial_s.mdl",
+ category = "Differential",
+ weight = Gear1SW,
+ parentable = true,
+ switch = 0.3,
+ maxtq = 25000,
+ gears = 1,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-TD-M", {
+ name = "Differential, Medium, Dual Clutch",
+ desc = "Medium duty differential",
+ model = "models/engines/transaxial_m.mdl",
+ category = "Differential",
+ weight = Gear1MW,
+ parentable = true,
+ switch = 0.4,
+ maxtq = 50000,
+ gears = 1,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "1Gear-TD-L", {
+ name = "Differential, Large, Dual Clutch",
+ desc = "Heavy duty differential, for the heaviest of engines",
+ model = "models/engines/transaxial_l.mdl",
+ category = "Differential",
+ weight = Gear1LW,
+ parentable = true,
+ switch = 0.6,
+ maxtq = 100000,
+ gears = 1,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ -1 ] = 1
+ }
+} )
diff --git a/lua/acf/shared/gearboxes/doublediff.lua b/lua/acf/shared/gearboxes/doublediff.lua
new file mode 100644
index 000000000..dfccf41ba
--- /dev/null
+++ b/lua/acf/shared/gearboxes/doublediff.lua
@@ -0,0 +1,75 @@
+-- Double Differential
+
+-- Weight
+local GearDDSW = 45
+local GearDDMW = 85
+local GearDDLW = 180
+
+-- Torque Rating
+local GearDDST = 20000
+local GearDDMT = 45000
+local GearDDLT = 100000
+
+-- general description
+local DDDesc = "\n\nA Double Differential transmission allows for a multitude of radii as well as a neutral steer."
+
+-- Inline
+
+ACF_DefineGearbox( "DoubleDiff-T-S", {
+ name = "Double Differential, Small",
+ desc = "A light duty regenerative steering transmission."..DDDesc,
+ model = "models/engines/transaxial_s.mdl",
+ category = "Regenerative Steering",
+ weight = GearDDSW,
+ parentable = true,
+ switch = 0.2,
+ maxtq = GearDDST,
+ gears = 1,
+ doublediff = true,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 1,
+ [ -1 ] = 1
+ }
+} )
+
+ACF_DefineGearbox( "DoubleDiff-T-M", {
+ name = "Double Differential, Medium",
+ desc = "A medium regenerative steering transmission."..DDDesc,
+ model = "models/engines/transaxial_m.mdl",
+ category = "Regenerative Steering",
+ weight = GearDDMW,
+ parentable = true,
+ switch = 0.35,
+ maxtq = GearDDMT,
+ gears = 1,
+ doublediff = true,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 1,
+ [ -1 ] = 1
+ }
+} )
+
+ACF_DefineGearbox( "DoubleDiff-T-L", {
+ name = "Double Differential, Large",
+ desc = "A heavy regenerative steering transmission."..DDDesc,
+ model = "models/engines/transaxial_l.mdl",
+ category = "Regenerative Steering",
+ weight = GearDDLW,
+ parentable = true,
+ switch = 0.5,
+ maxtq = GearDDLT,
+ gears = 1,
+ doublediff = true,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 1,
+ [ -1 ] = 1
+ }
+} )
+
+
diff --git a/lua/acf/shared/gearboxes/transfer.lua b/lua/acf/shared/gearboxes/transfer.lua
new file mode 100644
index 000000000..2739efe4b
--- /dev/null
+++ b/lua/acf/shared/gearboxes/transfer.lua
@@ -0,0 +1,124 @@
+
+-- Transfer cases
+
+local Gear2SW = 20
+local Gear2MW = 40
+local Gear2LW = 80
+
+-- Inline
+
+ACF_DefineGearbox( "2Gear-L-S", {
+ name = "Transfer case, Inline, Small",
+ desc = "2 speed gearbox, useful for low/high range and tank turning",
+ model = "models/engines/linear_s.mdl",
+ category = "Transfer",
+ weight = Gear2SW,
+ parentable = true,
+ switch = 0.3,
+ maxtq = 25000,
+ gears = 2,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ 2 ] = -0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "2Gear-L-M", {
+ name = "Transfer case, Inline, Medium",
+ desc = "2 speed gearbox, useful for low/high range and tank turning",
+ model = "models/engines/linear_m.mdl",
+ category = "Transfer",
+ weight = Gear2MW,
+ parentable = true,
+ switch = 0.4,
+ maxtq = 50000,
+ gears = 2,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ 2 ] = -0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "2Gear-L-L", {
+ name = "Transfer case, Inline, Large",
+ desc = "2 speed gearbox, useful for low/high range and tank turning",
+ model = "models/engines/linear_l.mdl",
+ category = "Transfer",
+ weight = Gear2LW,
+ parentable = true,
+ switch = 0.6,
+ maxtq = 100000,
+ gears = 2,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ 2 ] = -0.5,
+ [ -1 ] = 1
+ }
+} )
+
+-- Transaxial
+
+ACF_DefineGearbox( "2Gear-T-S", {
+ name = "Transfer case, Small",
+ desc = "2 speed gearbox, useful for low/high range and tank turning",
+ model = "models/engines/transaxial_s.mdl",
+ category = "Transfer",
+ weight = Gear2SW,
+ parentable = true,
+ switch = 0.3,
+ maxtq = 25000,
+ gears = 2,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ 2 ] = -0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "2Gear-T-M", {
+ name = "Transfer case, Medium",
+ desc = "2 speed gearbox, useful for low/high range and tank turning",
+ model = "models/engines/transaxial_m.mdl",
+ category = "Transfer",
+ weight = Gear2MW,
+ parentable = true,
+ switch = 0.4,
+ maxtq = 50000,
+ gears = 2,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ 2 ] = -0.5,
+ [ -1 ] = 0.5
+ }
+} )
+
+ACF_DefineGearbox( "2Gear-T-L", {
+ name = "Transfer case, Large",
+ desc = "2 speed gearbox, useful for low/high range and tank turning",
+ model = "models/engines/transaxial_l.mdl",
+ category = "Transfer",
+ weight = Gear2LW,
+ parentable = true,
+ switch = 0.6,
+ maxtq = 100000,
+ gears = 2,
+ doubleclutch = true,
+ geartable = {
+ [ 0 ] = 0,
+ [ 1 ] = 0.5,
+ [ 2 ] = -0.5,
+ [ -1 ] = 1
+ }
+} )
diff --git a/lua/acf/shared/guns/autocannon.lua b/lua/acf/shared/guns/autocannon.lua
new file mode 100644
index 000000000..71b2fb809
--- /dev/null
+++ b/lua/acf/shared/guns/autocannon.lua
@@ -0,0 +1,81 @@
+--define the class
+ACF_defineGunClass("AC", {
+ spread = 0.12,
+ name = "Autocannon",
+ desc = "Autocannons have a rather high weight and bulk for the ammo they fire, but they can fire it extremely fast.",
+ muzzleflash = "30mm_muzzleflash_noscale",
+ rofmod = 0.85,
+ sound = "weapons/ACF_Gun/ac_fire4.wav",
+ soundDistance = " ",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("20mmAC", { --id
+ name = "20mm Autocannon",
+ desc = "The 20mm AC is the smallest of the family; having a good rate of fire but a tiny shell.",
+ model = "models/autocannon/autocannon_20mm.mdl",
+ caliber = 2.0,
+ gunclass = "AC",
+ weight = 225,
+ year = 1930,
+ rofmod = 0.7,
+ magsize = 100,
+ magreload = 3,
+ round = {
+ maxlength = 32,
+ propweight = 0.13
+ }
+} )
+
+ACF_defineGun("30mmAC", {
+ name = "30mm Autocannon",
+ desc = "The 30mm AC can fire shells with sufficient space for a small payload, and has modest anti-armor capability",
+ model = "models/autocannon/autocannon_30mm.mdl",
+ gunclass = "AC",
+ caliber = 3.0,
+ weight = 960,
+ year = 1935,
+ rofmod = 0.5,
+ magsize = 75,
+ magreload = 3,
+ round = {
+ maxlength = 39,
+ propweight = 0.350
+ }
+} )
+
+ACF_defineGun("40mmAC", {
+ name = "40mm Autocannon",
+ desc = "The 40mm AC can fire shells with sufficient space for a useful payload, and can get decent penetration with proper rounds.",
+ model = "models/autocannon/autocannon_40mm.mdl",
+ gunclass = "AC",
+ caliber = 4.0,
+ weight = 1500,
+ year = 1940,
+ rofmod = 0.48,
+ magsize = 30,
+ magreload = 3,
+ round = {
+ maxlength = 45,
+ propweight = 0.9
+ }
+} )
+
+ACF_defineGun("50mmAC", {
+ name = "50mm Autocannon",
+ desc = "The 50mm AC fires shells comparable with the 50mm Cannon, making it capable of destroying light armour quite quickly.",
+ model = "models/autocannon/autocannon_50mm.mdl",
+ gunclass = "AC",
+ caliber = 5.0,
+ weight = 2130,
+ year = 1965,
+ rofmod = 0.4,
+ magsize = 20,
+ magreload = 3,
+ round = {
+ maxlength = 52,
+ propweight = 1.2
+ }
+} )
+
\ No newline at end of file
diff --git a/lua/acf/shared/guns/autoloader.lua b/lua/acf/shared/guns/autoloader.lua
new file mode 100644
index 000000000..c44d8c274
--- /dev/null
+++ b/lua/acf/shared/guns/autoloader.lua
@@ -0,0 +1,100 @@
+--define the class
+ACF_defineGunClass("AL", {
+ spread = 0.08,
+ name = "Autoloader",
+ desc = "A cannon with attached autoloading mechanism. While it allows for several quick shots, the mechanism adds considerable bulk, weight, and magazine reload time.",
+ muzzleflash = "120mm_muzzleflash_noscale",
+ rofmod = 0.64,
+ sound = "weapons/ACF_Gun/autoloader.wav",
+ soundDistance = "Cannon.Fire",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("75mmAL", { --id
+ name = "75mm Autoloading Cannon",
+ desc = "A quick-firing 75mm gun, pops off a number of rounds in relatively short order.",
+ model = "models/tankgun/tankgun_al_75mm.mdl",
+ gunclass = "AL",
+ caliber = 7.5,
+ weight = 1892,
+ year = 1946,
+ rofmod = 1,
+ magsize = 8,
+ magreload = 15,
+ round = {
+ maxlength = 78,
+ propweight = 3.8
+ }
+} )
+
+ACF_defineGun("100mmAL", {
+ name = "100mm Autoloading Cannon",
+ desc = "The 100mm is good for rapidly hitting medium armor, then running like your ass is on fire to reload.",
+ model = "models/tankgun/tankgun_al_100mm.mdl",
+ gunclass = "AL",
+ caliber = 10.0,
+ weight = 3325,
+ year = 1956,
+ rofmod = 0.85,
+ magsize = 6,
+ magreload = 21,
+ round = {
+ maxlength = 93,
+ propweight = 9.5
+ }
+} )
+
+ACF_defineGun("120mmAL", {
+ name = "120mm Autoloading Cannon",
+ desc = "The 120mm autoloader can do serious damage before reloading, but the reload time is killer.",
+ model = "models/tankgun/tankgun_al_120mm.mdl",
+ gunclass = "AL",
+ caliber = 12.0,
+ weight = 6050,
+ year = 1956,
+ rofmod = 0.757,
+ magsize = 5,
+ magreload = 27,
+ round = {
+ maxlength = 110,
+ propweight = 18
+ }
+} )
+
+ACF_defineGun("140mmAL", {
+ name = "140mm Autoloading Cannon",
+ desc = "The 140mm can shred a medium tank's armor with one magazine, and even function as shoot & scoot artillery, with its useful HE payload.",
+ model = "models/tankgun/tankgun_al_140mm.mdl",
+ gunclass = "AL",
+ caliber = 14.0,
+ weight = 8830,
+ year = 1970,
+ rofmod = 0.743,
+ magsize = 5,
+ magreload = 35,
+ round = {
+ maxlength = 127,
+ propweight = 28
+ }
+} )
+
+--[[
+ACF_defineGun("170mmAL", {
+ name = "170mm Autoloading Cannon",
+ desc = "The 170mm can shred an average 40ton tank's armor with one magazine.",
+ model = "models/tankgun/tankgun_al_170mm.mdl",
+ gunclass = "AL",
+ caliber = 17.0,
+ weight = 13350,
+ year = 1970,
+ rofmod = 0.8,
+ magsize = 4,
+ magreload = 40,
+ round = {
+ maxlength = 154,
+ propweight = 34
+ }
+} )
+]]--
+
diff --git a/lua/acf/shared/guns/cannon.lua b/lua/acf/shared/guns/cannon.lua
new file mode 100644
index 000000000..a308c1cec
--- /dev/null
+++ b/lua/acf/shared/guns/cannon.lua
@@ -0,0 +1,115 @@
+--define the class
+ACF_defineGunClass("C", {
+ spread = 0.08,
+ name = "Cannon",
+ desc = "High velocity guns that can fire very powerful ammunition, but are rather slow to reload.",
+ muzzleflash = "120mm_muzzleflash_noscale",
+ rofmod = 2,
+ sound = "weapons/ACF_Gun/cannon_new.wav",
+ soundDistance = "Cannon.Fire",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("37mmC", { --id
+ name = "37mm Cannon",
+ desc = "A light and fairly weak cannon with good accuracy.",
+ model = "models/tankgun/tankgun_37mm.mdl",
+ gunclass = "C",
+ caliber = 3.7,
+ weight = 350,
+ year = 1919,
+ rofmod = 1.4,
+ sound = "weapons/ACF_Gun/ac_fire4.wav",
+ round = {
+ maxlength = 48,
+ propweight = 1.125
+ }
+} )
+
+ACF_defineGun("50mmC", {
+ name = "50mm Cannon",
+ desc = "The 50mm is surprisingly fast-firing, with good effectiveness against light armor, but a pea-shooter compared to its bigger cousins",
+ model = "models/tankgun/tankgun_50mm.mdl",
+ gunclass = "C",
+ caliber = 5.0,
+ weight = 665,
+ year = 1935,
+ sound = "weapons/ACF_Gun/ac_fire4.wav",
+ round = {
+ maxlength = 63,
+ propweight = 2.1
+ }
+} )
+
+ACF_defineGun("75mmC", {
+ name = "75mm Cannon",
+ desc = "The 75mm is still rather respectable in rate of fire, but has only modest payload. Often found on the Eastern Front, and on cold war light tanks.",
+ model = "models/tankgun/tankgun_75mm.mdl",
+ gunclass = "C",
+ caliber = 7.5,
+ weight = 1420,
+ year = 1942,
+ round = {
+ maxlength = 78,
+ propweight = 3.8
+ }
+} )
+
+ACF_defineGun("100mmC", {
+ name = "100mm Cannon",
+ desc = "The 100mm was a benchmark for the early cold war period, and has great muzzle velocity and hitting power, while still boasting a respectable, if small, payload.",
+ model = "models/tankgun/tankgun_100mm.mdl",
+ gunclass = "C",
+ caliber = 10.0,
+ weight = 2750,
+ year = 1944,
+ round = {
+ maxlength = 93,
+ propweight = 9.5
+ }
+} )
+
+ACF_defineGun("120mmC", {
+ name = "120mm Cannon",
+ desc = "Often found in MBTs, the 120mm shreds lighter armor with utter impunity, and is formidable against even the big boys.",
+ model = "models/tankgun/tankgun_120mm.mdl",
+ gunclass = "C",
+ caliber = 12.0,
+ weight = 5200,
+ year = 1955,
+ round = {
+ maxlength = 110,
+ propweight = 18
+ }
+} )
+
+ACF_defineGun("140mmC", {
+ name = "140mm Cannon",
+ desc = "The 140mm fires a massive shell with enormous penetrative capability, but has a glacial reload speed and a very hefty weight.",
+ model = "models/tankgun/tankgun_140mm.mdl",
+ gunclass = "C",
+ caliber = 14.0,
+ weight = 8180,
+ year = 1990,
+ round = {
+ maxlength = 127,
+ propweight = 28
+ }
+} )
+
+--[[
+ACF_defineGun("170mmC", {
+ name = "170mm Cannon",
+ desc = "The 170mm fires a gigantic shell with ginormous penetrative capability, but has a glacial reload speed and an extremely hefty weight.",
+ model = "models/tankgun/tankgun_170mm.mdl",
+ gunclass = "C",
+ caliber = 17.0,
+ weight = 12350,
+ year = 1990,
+ round = {
+ maxlength = 154,
+ propweight = 34
+ }
+} )
+]]--
diff --git a/lua/acf/shared/guns/grenadelauncher.lua b/lua/acf/shared/guns/grenadelauncher.lua
new file mode 100644
index 000000000..65db7ce57
--- /dev/null
+++ b/lua/acf/shared/guns/grenadelauncher.lua
@@ -0,0 +1,28 @@
+--define the class
+ACF_defineGunClass("GL", {
+ spread = 0.32,
+ name = "Grenade Launcher",
+ desc = "Grenade Launchers can fire shells with relatively large payloads at a fast rate, but with very limited velocities and poor accuracy.",
+ muzzleflash = "40mm_muzzleflash_noscale",
+ rofmod = 1,
+ sound = "weapons/acf_gun/grenadelauncher.wav",
+ soundDistance = " ",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("40mmGL", { --id
+ name = "40mm Grenade Launcher",
+ desc = "The 40mm chews up infantry but is about as useful as tits on a nun for fighting armor. Often found on 4x4s rolling through the third world.",
+ model = "models/launcher/40mmgl.mdl",
+ gunclass = "GL",
+ caliber = 4.0,
+ weight = 55,
+ magsize = 6,
+ magreload = 7.5,
+ year = 1970,
+ round = {
+ maxlength = 7.5,
+ propweight = 0.01
+ }
+} )
diff --git a/lua/acf/shared/guns/heavymachinegun.lua b/lua/acf/shared/guns/heavymachinegun.lua
new file mode 100644
index 000000000..b7c042b10
--- /dev/null
+++ b/lua/acf/shared/guns/heavymachinegun.lua
@@ -0,0 +1,87 @@
+--define the class
+ACF_defineGunClass("HMG", {
+ spread = 0.4,
+ name = "Heavy Machinegun",
+ desc = "Designed as autocannons for aircraft, HMGs are rapid firing, lightweight, and compact but sacrifice accuracy, magazine size, and reload times. They excel at strafing and dogfighting.\nBecause of their long reload times and high rate of fire, it is best to aim BEFORE pushing the almighty fire switch.",
+ muzzleflash = "50cal_muzzleflash_noscale",
+ rofmod = 0.14,
+ sound = "weapons/ACF_Gun/mg_fire3.wav",
+ soundDistance = " ",
+ soundNormal = " ",
+ longbarrel = {
+ index = 2,
+ submodel = 4,
+ newpos = "muzzle2"
+ }
+} )
+
+--add a gun to the class
+
+ACF_defineGun("13mmHMG", {
+ name = "13mm Heavy Machinegun",
+ desc = "The lightest of the HMGs, the 13mm has a rapid fire rate but suffers from poor payload size. Often used to strafe ground troops or annoy low-flying aircraft.",
+ model = "models/machinegun/machinegun_20mm.mdl",
+ gunclass = "HMG",
+ caliber = 1.3,
+ weight = 90,
+ year = 1935,
+ rofmod = 3.3,
+ magsize = 35,
+ magreload = 6,
+ round = {
+ maxlength = 22,
+ propweight = 0.09
+ }
+} )
+
+ACF_defineGun("20mmHMG", {
+ name = "20mm Heavy Machinegun",
+ desc = "The 20mm has a rapid fire rate but suffers from poor payload size. Often used to strafe ground troops or annoy low-flying aircraft.",
+ model = "models/machinegun/machinegun_20mm_compact.mdl",
+ gunclass = "HMG",
+ caliber = 2.0,
+ weight = 160,
+ year = 1935,
+ rofmod = 1.9, --at 1.5, 675rpm; at 2.0, 480rpm
+ magsize = 30,
+ magreload = 6,
+ round = {
+ maxlength = 30,
+ propweight = 0.12
+ }
+} )
+
+ACF_defineGun("30mmHMG", {
+ name = "30mm Heavy Machinegun",
+ desc = "30mm shell chucker, light and compact. Your average cold war dogfight go-to.",
+ model = "models/machinegun/machinegun_30mm_compact.mdl",
+ gunclass = "HMG",
+ caliber = 3.0,
+ weight = 480,
+ year = 1941,
+ rofmod = 1.1, --at 1.05, 495rpm;
+ magsize = 25,
+ magreload = 6,
+ round = {
+ maxlength = 37,
+ propweight = 0.35
+ }
+} )
+
+ACF_defineGun("40mmHMG", {
+ name = "40mm Heavy Machinegun",
+ desc = "The heaviest of the heavy machineguns. Massively powerful with a killer reload and hefty ammunition requirements, it can pop even relatively heavy targets with ease.",
+ model = "models/machinegun/machinegun_40mm_compact.mdl",
+ gunclass = "HMG",
+ caliber = 4.0,
+ weight = 780,
+ year = 1955,
+ rofmod = 0.95, --at 0.75, 455rpm
+ magsize = 20,
+ magreload = 8,
+ round = {
+ maxlength = 42,
+ propweight = 0.9
+ }
+} )
+
diff --git a/lua/acf/shared/guns/howitzer.lua b/lua/acf/shared/guns/howitzer.lua
new file mode 100644
index 000000000..870355c9e
--- /dev/null
+++ b/lua/acf/shared/guns/howitzer.lua
@@ -0,0 +1,112 @@
+--define the class
+ACF_defineGunClass("HW", {
+ spread = 0.12,
+ name = "Howitzer",
+ desc = "Howitzers are limited to rather mediocre muzzle velocities, but can fire extremely heavy projectiles with large useful payload capacities.",
+ muzzleflash = "120mm_muzzleflash_noscale",
+ rofmod = 1.8,
+ sound = "weapons/ACF_Gun/howitzer_new2.wav",
+ soundDistance = "Howitzer.Fire",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("75mmHW", { --id
+ name = "75mm Howitzer",
+ desc = "Often found being towed by large smelly animals, the 75mm has a high rate of fire, and is surprisingly lethal against light armor. Great for a sustained barrage against someone you really don't like.",
+ model = "models/howitzer/howitzer_75mm.mdl",
+ gunclass = "HW",
+ caliber = 7.5,
+ weight = 530,
+ year = 1900,
+ round = {
+ maxlength = 60,
+ propweight = 1.8
+ }
+} )
+
+ACF_defineGun("105mmHW", {
+ name = "105mm Howitzer",
+ desc = "The 105 lobs a big shell far, and its HEAT rounds can be extremely effective against even heavier armor.",
+ model = "models/howitzer/howitzer_105mm.mdl",
+ gunclass = "HW",
+ caliber = 10.5,
+ weight = 1480,
+ year = 1900,
+ round = {
+ maxlength = 86,
+ propweight = 3.75
+ }
+} )
+
+ACF_defineGun("122mmHW", {
+ name = "122mm Howitzer",
+ desc = "The 122mm bridges the gap between the 105 and the 155, providing a lethal round with a big splash radius.",
+ model = "models/howitzer/howitzer_122mm.mdl",
+ gunclass = "HW",
+ caliber = 12.2,
+ weight = 3420,
+ year = 1900,
+ round = {
+ maxlength = 106,
+ propweight = 7
+ }
+} )
+
+ACF_defineGun("155mmHW", {
+ name = "155mm Howitzer",
+ desc = "The 155 is a classic heavy artillery round, with good reason. A versatile weapon, it's found on most modern SPGs.",
+ model = "models/howitzer/howitzer_155mm.mdl",
+ gunclass = "HW",
+ caliber = 15.5,
+ weight = 5340,
+ year = 1900,
+ round = {
+ maxlength = 124,
+ propweight = 13.5
+ }
+} )
+
+ACF_defineGun("203mmHW", {
+ name = "203mm Howitzer",
+ desc = "An 8-inch deck gun, found on siege artillery and cruisers.",
+ model = "models/howitzer/howitzer_203mm.mdl",
+ gunclass = "HW",
+ caliber = 20.3,
+ weight = 10280,
+ year = 1900,
+ round = {
+ maxlength = 162.4,
+ propweight = 28.5
+ }
+} )
+
+--[[
+ACF_defineGun("240mmHW", {
+ name = "240mm Howitzer",
+ desc = "A 9.4-inch deck gun, found on heavy siege artillery and cruisers.",
+ model = "models/howitzer/howitzer_240mm.mdl",
+ gunclass = "HW",
+ caliber = 24.0,
+ weight = 12980,
+ year = 1900,
+ round = {
+ maxlength = 192.0,
+ propweight = 33.7
+ }
+} )
+
+ACF_defineGun("290mmHW", {
+ name = "290mm Howitzer",
+ desc = " Mother of all howitzers. This 12in beast can be found on battleships. It WILL fuck your day up... when it reloads.",
+ model = "models/howitzer/howitzer_406mm.mdl",
+ gunclass = "HW",
+ caliber = 29,
+ weight = 24960,
+ year = 1900,
+ round = {
+ maxlength = 325,
+ propweight = 57.0
+ }
+} )
+]]--
\ No newline at end of file
diff --git a/lua/acf/shared/guns/machinegun.lua b/lua/acf/shared/guns/machinegun.lua
new file mode 100644
index 000000000..6887ed469
--- /dev/null
+++ b/lua/acf/shared/guns/machinegun.lua
@@ -0,0 +1,83 @@
+--define the class
+ACF_defineGunClass("MG", {
+ spread = 0.24,
+ name = "Machinegun",
+ desc = "Machineguns are light guns that fire equally light bullets at a fast rate.",
+ muzzleflash = "50cal_muzzleflash_noscale",
+ rofmod = 0.9,
+ sound = "weapons/ACF_Gun/mg_fire4.wav",
+ soundNormal = "weapons/ACF_Gun/mg_fire4.wav",
+ soundDistance = "",
+} )
+
+--add a gun to the class
+ACF_defineGun("7.62mmMG", { --id
+ name = "7.62mm Machinegun",
+ desc = "The 7.62mm is effective against infantry, but its usefulness against armor is laughable at best.",
+ model = "models/machinegun/machinegun_762mm.mdl",
+ gunclass = "MG",
+ canparent = true,
+ caliber = 0.762,
+ weight = 15,
+ year = 1930,
+ rofmod = 1.59,
+ magsize = 250,
+ magreload = 6,
+ round = {
+ maxlength = 13,
+ propweight = 0.04
+ }
+} )
+
+ACF_defineGun("12.7mmMG", {
+ name = "12.7mm Machinegun",
+ desc = "The 12.7mm MG is still light, finding its way into a lot of mountings, including on top of tanks.",
+ model = "models/machinegun/machinegun_127mm.mdl",
+ gunclass = "MG",
+ canparent = true,
+ caliber = 1.27,
+ weight = 30,
+ year = 1910,
+ rofmod = 1, --0.766
+ magsize = 150,
+ magreload = 6,
+ round = {
+ maxlength = 15.8,
+ propweight = 0.03
+ }
+} )
+
+ACF_defineGun("14.5mmMG", {
+ name = "14.5mm Machinegun",
+ desc = "The 14.5mm MG trades its smaller stablemates' rate of fire for more armor penetration and damage.",
+ model = "models/machinegun/machinegun_145mm.mdl",
+ gunclass = "MG",
+ canparent = true,
+ caliber = 1.45,
+ weight = 45,
+ year = 1932,
+ rofmod = 1, --0.722
+ magsize = 90,
+ magreload = 5,
+ round = {
+ maxlength = 19.5,
+ propweight = 0.04
+ }
+} )
+
+--ACF_defineGun("20mmMG", {
+ --name = "20mm Machinegun",
+ --desc = "The 20mm MG is practically a cannon in its own right; the weight and recoil made it difficult to mount on light land vehicles, though it was adapted for use on both aircraft and ships.",
+ --model = "models/machinegun/machinegun_20mm.mdl",
+ --gunclass = "MG",
+ --caliber = 2.0,
+ --weight = 95,
+ --year = 1935,
+ --rofmod = 0.3,
+ --magsize = 50,
+ --magreload = 4,
+ --round = {
+ --maxlength = 22,
+ --propweight = 0.09
+ --}
+--} )
diff --git a/lua/acf/shared/guns/mortar.lua b/lua/acf/shared/guns/mortar.lua
new file mode 100644
index 000000000..463b2b951
--- /dev/null
+++ b/lua/acf/shared/guns/mortar.lua
@@ -0,0 +1,99 @@
+--define the class
+ACF_defineGunClass("MO", {
+ spread = 0.64,
+ name = "Mortar",
+ desc = "Mortars are able to fire shells with usefull payloads from a light weight gun, at the price of limited velocities.",
+ muzzleflash = "40mm_muzzleflash_noscale",
+ rofmod = 2.5,
+ sound = "weapons/ACF_Gun/mortar_new.wav",
+ soundDistance = "Mortar.Fire",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("60mmM", { --id
+ name = "60mm Mortar",
+ desc = "The 60mm is a common light infantry support weapon, with a high rate of fire but a puny payload.",
+ model = "models/mortar/mortar_60mm.mdl",
+ gunclass = "MO",
+ caliber = 6.0,
+ weight = 60,
+ rofmod = 1.25,
+ year = 1930,
+ round = {
+ maxlength = 20,
+ propweight = 0.037
+ }
+} )
+
+ACF_defineGun("80mmM", {
+ name = "80mm Mortar",
+ desc = "The 80mm is a common infantry support weapon, with a good bit more boom than its little cousin.",
+ model = "models/mortar/mortar_80mm.mdl",
+ gunclass = "MO",
+ caliber = 8.0,
+ weight = 120,
+ year = 1930,
+ round = {
+ maxlength = 28,
+ propweight = 0.055
+ }
+} )
+
+ACF_defineGun("120mmM", {
+ name = "120mm Mortar",
+ desc = "The versatile 120 is sometimes vehicle-mounted to provide quick boomsplat to support the infantry. Carries more boom in its boomsplat, has good HEAT performance, and is more accurate in high-angle firing.",
+ model = "models/mortar/mortar_120mm.mdl",
+ gunclass = "MO",
+ caliber = 12.0,
+ weight = 640,
+ year = 1935,
+ round = {
+ maxlength = 45,
+ propweight = 0.175
+ }
+} )
+
+ACF_defineGun("150mmM", {
+ name = "150mm Mortar",
+ desc = "The perfect balance between the 120mm and the 200mm. Can prove a worthy main gun weapon, as well as a mighty good mortar emplacement",
+ model = "models/mortar/mortar_150mm.mdl",
+ gunclass = "MO",
+ caliber = 15.0,
+ weight = 1255,
+ year = 1945,
+ round = {
+ maxlength = 58,
+ propweight = 0.235
+ }
+} )
+
+ACF_defineGun("200mmM", {
+ name = "200mm Mortar",
+ desc = "The 200mm is a beast, often used against fortifications. Though enormously powerful, feel free to take a nap while it reloads",
+ model = "models/mortar/mortar_200mm.mdl",
+ gunclass = "MO",
+ caliber = 20.0,
+ weight = 2850,
+ year = 1940,
+ round = {
+ maxlength = 80,
+ propweight = 0.330
+ }
+} )
+
+--[[
+ACF_defineGun("280mmM", {
+ name = "280mm Mortar",
+ desc = "Massive payload, with a reload time to match. Found in rare WW2 siege artillery pieces. It's the perfect size for a jeep.",
+ model = "models/mortar/mortar_280mm.mdl",
+ gunclass = "MO",
+ caliber = 28.0,
+ weight = 9035,
+ year = 1945,
+ round = {
+ maxlength = 138,
+ propweight = 0.462
+ }
+} )
+]]--
diff --git a/lua/acf/shared/guns/rotaryautocannon.lua b/lua/acf/shared/guns/rotaryautocannon.lua
new file mode 100644
index 000000000..52a8c02b8
--- /dev/null
+++ b/lua/acf/shared/guns/rotaryautocannon.lua
@@ -0,0 +1,99 @@
+--define the class
+ACF_defineGunClass("RAC", {
+ spread = 0.4,
+ name = "Rotary Autocannon",
+ desc = "Rotary Autocannons sacrifice weight, bulk and accuracy over classic Autocannons to get the highest rate of fire possible.",
+ muzzleflash = "50cal_muzzleflash_noscale",
+ rofmod = 0.07,
+ sound = "weapons/acf_gun/mg_fire3.wav",
+ soundDistance = " ",
+ soundNormal = " ",
+ color = {135, 135, 135}
+} )
+
+ACF_defineGun("14.5mmRAC", { --id
+ name = "14.5mm Rotary Autocannon",
+ desc = "A lightweight rotary autocannon, used primarily against infantry and light vehicles. It has a lower firerate than its larger brethren, but a significantly quicker cooldown period as well.",
+ model = "models/rotarycannon/kw/14_5mmrac.mdl",
+ gunclass = "RAC",
+ caliber = 1.45,
+ weight = 240,
+ year = 1962,
+ magsize = 60,
+ magreload = 6,
+ rofmod = 5.4,
+ round = {
+ maxlength = 25,
+ propweight = 0.06
+ }
+} )
+
+ACF_defineGun("20mmRAC", {
+ name = "20mm Rotary Autocannon",
+ desc = "The 20mm is able to chew up light armor with decent penetration or put up a big flak screen. Typically mounted on ground attack aircraft, SPAAGs and the ocassional APC. Suffers from a moderate cooldown period between bursts to avoid overheating the barrels.",
+ model = "models/rotarycannon/kw/20mmrac.mdl",
+ gunclass = "RAC",
+ caliber = 2.0,
+ weight = 760,
+ year = 1965,
+ magsize = 40,
+ magreload = 7,
+ rofmod = 2.1,
+ round = {
+ maxlength = 30,
+ propweight = 0.12
+ }
+} )
+
+ACF_defineGun("30mmRAC", {
+ name = "30mm Rotary Autocannon",
+ desc = "The 30mm is the bane of ground-attack aircraft, able to tear up light armor without giving one single fuck. Also seen in the skies above dead T-72s. Has a moderate cooldown period between bursts to avoid overheating the barrels.",
+ model = "models/rotarycannon/kw/30mmrac.mdl",
+ gunclass = "RAC",
+ caliber = 3.0,
+ weight = 1500,
+ year = 1975,
+ magsize = 40,
+ magreload = 8,
+ rofmod = 1,
+ round = {
+ maxlength = 40,
+ propweight = 0.350
+ }
+} )
+
+
+ACF_defineGun("20mmHRAC", {
+ name = "20mm Heavy Rotary Autocannon",
+ desc = "A reinforced, heavy-duty 20mm rotary autocannon, able to fire heavier rounds with a larger magazine. Phalanx.",
+ model = "models/rotarycannon/kw/20mmrac.mdl",
+ gunclass = "RAC",
+ caliber = 2.0,
+ weight = 1200,
+ year = 1981,
+ magsize = 60,
+ magreload = 4,
+ rofmod = 2.5,
+ round = {
+ maxlength = 36,
+ propweight = 0.12
+ }
+} )
+
+ACF_defineGun("30mmHRAC", {
+ name = "30mm Heavy Rotary Autocannon",
+ desc = "A reinforced, heavy duty 30mm rotary autocannon, able to fire heavier rounds with a larger magazine. Keeper of goals.",
+ model = "models/rotarycannon/kw/30mmrac.mdl",
+ gunclass = "RAC",
+ caliber = 3.0,
+ weight = 2850,
+ year = 1985,
+ magsize = 50,
+ magreload = 6,
+ rofmod = 1.2,
+ round = {
+ maxlength = 45,
+ propweight = 0.350
+ }
+} )
+
diff --git a/lua/acf/shared/guns/semiauto.lua b/lua/acf/shared/guns/semiauto.lua
new file mode 100644
index 000000000..77163a42e
--- /dev/null
+++ b/lua/acf/shared/guns/semiauto.lua
@@ -0,0 +1,97 @@
+--define the class
+ACF_defineGunClass("SA", {
+ spread = 0.1,
+ name = "Semiautomatic Cannon",
+ desc = "Semiautomatic cannons offer better payloads than autocannons and less weight at the cost of rate of fire.",
+ muzzleflash = "30mm_muzzleflash_noscale",
+ rofmod = 0.36,
+ sound = "acf_extra/tankfx/gnomefather/25mm1.wav",
+ soundDistance = " ",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("25mmSA", { --id
+ name = "25mm Semiautomatic Cannon",
+ desc = "The 25mm semiauto can quickly put five rounds downrange, being lethal, yet light.",
+ model = "models/autocannon/semiautocannon_25mm.mdl",
+ gunclass = "SA",
+ caliber = 2.5,
+ weight = 200,
+ year = 1935,
+ rofmod = 0.7,
+ magsize = 5,
+ magreload = 2,
+ round = {
+ maxlength = 39,
+ propweight = 0.5
+ }
+} )
+
+ACF_defineGun("37mmSA", {
+ name = "37mm Semiautomatic Cannon",
+ desc = "The 37mm is surprisingly powerful, its five-round clips boasting a respectable payload and a high muzzle velocity.",
+ model = "models/autocannon/semiautocannon_37mm.mdl",
+ gunclass = "SA",
+ caliber = 3.7,
+ weight = 540,
+ year = 1940,
+ rofmod = 0.7,
+ magsize = 5,
+ magreload = 3.5,
+ round = {
+ maxlength = 42,
+ propweight = 1.125
+ }
+} )
+
+ACF_defineGun("45mmSA", {
+ name = "45mm Semiautomatic Cannon",
+ desc = "The 45mm can easily shred light armor, with a respectable rate of fire, but its armor penetration pales in comparison to regular cannons.",
+ model = "models/autocannon/semiautocannon_45mm.mdl",
+ gunclass = "SA",
+ caliber = 4.5,
+ weight = 870,
+ year = 1965,
+ rofmod = 0.72,
+ magsize = 5,
+ magreload = 4,
+ round = {
+ maxlength = 52,
+ propweight = 1.8
+ }
+} )
+
+ACF_defineGun("57mmSA", {
+ name = "57mm Semiautomatic Cannon",
+ desc = "The 57mm is a respectable light armament, offering considerable penetration and moderate fire rate.",
+ model = "models/autocannon/semiautocannon_57mm.mdl",
+ gunclass = "SA",
+ caliber = 5.7,
+ weight = 1560,
+ year = 1965,
+ rofmod = 0.8,
+ magsize = 5,
+ magreload = 4.5,
+ round = {
+ maxlength = 62,
+ propweight = 2
+ }
+} )
+
+ACF_defineGun("76mmSA", {
+ name = "76mm Semiautomatic Cannon",
+ desc = "The 76mm semiauto is a fearsome weapon, able to put 5 76mm rounds downrange in 8 seconds.",
+ model = "models/autocannon/semiautocannon_76mm.mdl",
+ gunclass = "SA",
+ caliber = 7.62,
+ weight = 2990,
+ year = 1984,
+ rofmod = 0.85,
+ magsize = 5,
+ magreload = 5,
+ round = {
+ maxlength = 70,
+ propweight = 4.75
+ }
+} )
diff --git a/lua/acf/shared/guns/shortcannon.lua b/lua/acf/shared/guns/shortcannon.lua
new file mode 100644
index 000000000..a5cbe65dd
--- /dev/null
+++ b/lua/acf/shared/guns/shortcannon.lua
@@ -0,0 +1,100 @@
+--define the class
+ACF_defineGunClass("SC", {
+ spread = 0.2,
+ name = "Short-Barrel Cannon",
+ desc = "Short cannons trade muzzle velocity and accuracy for lighter weight and smaller size, with more penetration than howitzers and lighter than cannons.",
+ muzzleflash = "120mm_muzzleflash_noscale",
+ rofmod = 1.7,
+ sound = "weapons/ACF_Gun/cannon_new.wav",
+ soundDistance = "Cannon.Fire",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("37mmSC", {
+ name = "37mm Short Cannon",
+ desc = "Quick-firing and light, but penetration is laughable. You're better off throwing rocks.",
+ model = "models/tankgun/tankgun_short_37mm.mdl",
+ gunclass = "SC",
+ caliber = 3.7,
+ weight = 200,
+ rofmod = 1.4,
+ year = 1915,
+ sound = "weapons/ACF_Gun/ac_fire4.wav",
+ round = {
+ maxlength = 45,
+ propweight = 0.29
+ }
+} )
+
+ACF_defineGun("50mmSC", {
+ name = "50mm Short Cannon",
+ desc = "The 50mm is a quick-firing pea-shooter, good for scouts, and common on old interwar tanks.",
+ model = "models/tankgun/tankgun_short_50mm.mdl",
+ gunclass = "SC",
+ caliber = 5.0,
+ weight = 330,
+ rofmod = 1.4,
+ year = 1915,
+ sound = "weapons/ACF_Gun/ac_fire4.wav",
+ round = {
+ maxlength = 63,
+ propweight = 0.6,
+ }
+} )
+
+ACF_defineGun("75mmSC", {
+ name = "75mm Short Cannon",
+ desc = "The 75mm is common WW2 medium tank armament, and still useful in many other applications.",
+ model = "models/tankgun/tankgun_short_75mm.mdl",
+ gunclass = "SC",
+ caliber = 7.5,
+ weight = 750,
+ year = 1936,
+ round = {
+ maxlength = 76,
+ propweight = 2
+ }
+} )
+
+ACF_defineGun("100mmSC", {
+ name = "100mm Short Cannon",
+ desc = "The 100mm is an effective infantry-support or antitank weapon, with a lot of uses and surprising lethality.",
+ model = "models/tankgun/tankgun_short_100mm.mdl",
+ gunclass = "SC",
+ caliber = 10.0,
+ weight = 1750,
+ year = 1940,
+ round = {
+ maxlength = 93,
+ propweight = 4.5
+ }
+} )
+
+ACF_defineGun("120mmSC", {
+ name = "120mm Short Cannon",
+ desc = "The 120mm is a formidable yet lightweight weapon, with excellent performance against larger vehicles.",
+ model = "models/tankgun/tankgun_short_120mm.mdl",
+ gunclass = "SC",
+ caliber = 12.0,
+ weight = 3800,
+ year = 1944,
+ round = {
+ maxlength = 110,
+ propweight = 8.5
+ }
+} )
+
+ACF_defineGun("140mmSC", {
+ name = "140mm Short Cannon",
+ desc = "A specialized weapon, developed from dark magic and anti-heavy tank hatred. Deal with it.",
+ model = "models/tankgun/tankgun_short_140mm.mdl",
+ gunclass = "SC",
+ caliber = 14.0,
+ weight = 6040,
+ year = 1999,
+ round = {
+ maxlength = 127,
+ propweight = 12.8
+ }
+} )
diff --git a/lua/acf/shared/guns/smokelauncher.lua b/lua/acf/shared/guns/smokelauncher.lua
new file mode 100644
index 000000000..24b5642ba
--- /dev/null
+++ b/lua/acf/shared/guns/smokelauncher.lua
@@ -0,0 +1,46 @@
+--define the class
+ACF_defineGunClass("SL", {
+ spread = 0.32,
+ name = "Smoke Launcher",
+ desc = "Smoke launcher to block an attacker's line of sight.",
+ muzzleflash = "40mm_muzzleflash_noscale",
+ rofmod = 45,
+ sound = "weapons/acf_gun/smoke_launch.wav",
+ soundDistance = "Mortar.Fire",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+ACF_defineGun("40mmSL", { --id
+ name = "40mm Smoke Launcher",
+ desc = "",
+ model = "models/launcher/40mmsl.mdl",
+ gunclass = "SL",
+ canparent = true,
+ caliber = 4.0,
+ weight = 1,
+ year = 1941,
+ round = {
+ maxlength = 17.5,
+ propweight = 0.000075
+ }
+} )
+
+--add a gun to the class
+ACF_defineGun("40mmCL", { --id
+ name = "40mm Countermeasure Launcher",
+ desc = "A revolver-style launcher capable of firing off several smoke or flare rounds.",
+ model = "models/launcher/40mmgl.mdl",
+ gunclass = "SL",
+ canparent = true,
+ caliber = 4.0,
+ weight = 20,
+ rofmod = 0.015,
+ magsize = 6,
+ magreload = 40,
+ year = 1950,
+ round = {
+ maxlength = 12,
+ propweight = 0.001
+ }
+} )
diff --git a/lua/acf/shared/guns/smoothbore.lua b/lua/acf/shared/guns/smoothbore.lua
new file mode 100644
index 000000000..c9ef9fca3
--- /dev/null
+++ b/lua/acf/shared/guns/smoothbore.lua
@@ -0,0 +1,72 @@
+--define the class
+ACF_defineGunClass("SB", {
+ spread = 0.08,
+ name = "Smoothbore Cannon",
+ desc = "More modern smoothbore cannons that can only fire munitions that do not rely on spinning for accuracy.",
+ muzzleflash = "120mm_muzzleflash_noscale",
+ rofmod = 1.72,
+ sound = "weapons/ACF_Gun/cannon_new.wav",
+ soundDistance = "Cannon.Fire",
+ soundNormal = " "
+} )
+
+--add a gun to the class
+
+
+ACF_defineGun("105mmSB", {
+ name = "105mm Smoothbore Cannon",
+ desc = "The 105mm was a benchmark for the early cold war period, and has great muzzle velocity and hitting power, while still boasting a respectable, if small, payload.",
+ model = "models/tankgun_old/tankgun_100mm.mdl",
+ gunclass = "SB",
+ caliber = 10.5,
+ weight = 3550,
+ year = 1970,
+ round = {
+ maxlength = 93+8,
+ propweight = 9
+ }
+} )
+
+ACF_defineGun("120mmSB", {
+ name = "120mm Smoothbore Cannon",
+ desc = "Often found in MBTs, the 120mm shreds lighter armor with utter impunity, and is formidable against even the big boys.",
+ model = "models/tankgun_old/tankgun_120mm.mdl",
+ gunclass = "SB",
+ caliber = 12.0,
+ weight = 6000,
+ year = 1975,
+ round = {
+ maxlength = 110+13,
+ propweight = 18
+ }
+} )
+
+ACF_defineGun("140mmSB", {
+ name = "140mm Smoothbore Cannonn",
+ desc = "The 140mm fires a massive shell with enormous penetrative capability, but has a glacial reload speed and a very hefty weight.",
+ model = "models/tankgun_old/tankgun_140mm.mdl",
+ gunclass = "SB",
+ caliber = 14.0,
+ weight = 8980,
+ year = 1990,
+ round = {
+ maxlength = 127+18,
+ propweight = 28
+ }
+} )
+
+--[[
+ACF_defineGun("170mmC", {
+ name = "170mm Cannon",
+ desc = "The 170mm fires a gigantic shell with ginormous penetrative capability, but has a glacial reload speed and an extremely hefty weight.",
+ model = "models/tankgun/tankgun_170mm.mdl",
+ gunclass = "C",
+ caliber = 17.0,
+ weight = 12350,
+ year = 1990,
+ round = {
+ maxlength = 154,
+ propweight = 34
+ }
+} )
+]]--
diff --git a/lua/acf/shared/rounds/roundap.lua b/lua/acf/shared/rounds/roundap.lua
new file mode 100644
index 000000000..fa68441c2
--- /dev/null
+++ b/lua/acf/shared/rounds/roundap.lua
@@ -0,0 +1,264 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.AP = { "MO", "SL", "SB" }
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Armour Piercing (AP)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A shell made out of a solid piece of steel, meant to penetrate armour"
+Round.netid = 1 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ Data.ProjMass = Data.FrAera * (Data.ProjLength*7.9/1000) --Volume of the projectile as a cylinder * density of steel
+ Data.ShovePower = 0.2
+ Data.PenAera = Data.FrAera^ACF.PenAreaMod
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 800 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ Data.BoomPower = Data.PropMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+ GUIData.MaxPen = (Energy.Penetration/Data.PenAera)*ACF.KEtoRHA
+ return GUIData
+end
+
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "AP" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ --local FrAera = BulletData.FrAera
+ local DData = Round.getDisplayData(BulletData)
+
+ --fakeent.ACF.Armour = DData.MaxPen or 0
+ --fakepen.Penetration = (DData.MaxPen * FrAera) / ACF.KEtoRHA
+ --local fakepen = ACF_Kinetic( BulletData.SlugMV*39.37 , BulletData.SlugMass, 9999999 )
+ --local MaxHP = ACF_CalcDamage( fakeent , fakepen , FrAera , 0 )
+
+ --[[
+ local TotalMass = BulletData.ProjMass + BulletData.PropMass
+ local MassUnit
+
+ if TotalMass < 0.1 then
+ TotalMass = TotalMass * 1000
+ MassUnit = " g"
+ else
+ MassUnit = " kg"
+ end
+ ]]--
+
+ local str =
+ {
+ --"Cartridge Mass: ", math.Round(TotalMass, 2), MassUnit, "\n",
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm"
+ --"Max Pen. Damage: ", math.Round(MaxHP.Damage, 1), " HP\n",
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet.Filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet.Flight , Bullet.Filter , Energy.Kinetic*HitRes.Loss , Bullet.Caliber , Target.ACF.Armour , Bullet.Owner ) --Do some spalling
+ Bullet.Flight = Bullet.Flight:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet.ProjMass)^0.5 * 39.37
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+ else
+ table.insert( Bullet.Filter , Target )
+ return "Penetrated" end
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos )
+
+ ACF_RemoveBullet( Index )
+
+end
+
+-- Bullet stops here
+function Round.endeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Impact", Spall )
+
+end
+
+-- Bullet penetrated something
+function Round.pierceeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+end
+
+-- Bullet ricocheted off something
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.AP )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "AP" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m\\s") --Proj muzzle velocity (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+
+ acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+
+end
+
+list.Set( "ACFRoundTypes", "AP", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "AP" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundapcr.lua b/lua/acf/shared/rounds/roundapcr.lua
new file mode 100644
index 000000000..85de94e60
--- /dev/null
+++ b/lua/acf/shared/rounds/roundapcr.lua
@@ -0,0 +1,266 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.APCR = { "MO", "SL", "HW" , "C", "AC", "SA", "MG" , "SB", "RAC", "GL", "HMG", "AAM", "ARTY", "ASM", "BOMB", "GBU", "POD", "SAM", "UAR", "FFAR", "FGL" }
+
+local Round = {}
+local PenMod = 1.5
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Armor Piercing, Composite Rigid (APCR)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A hardened core munition designed for weapons in the 1940s. Short Cannons only."
+Round.netid = 11 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ Data.ProjMass = (Data.FrAera/5) * (Data.ProjLength*7.9/1000) --Volume of the projectile as a cylinder * density of steel
+ Data.ShovePower = 0.2
+ Data.PenAera = (Data.FrAera^ACF.PenAreaMod)/3.1
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 500 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ Data.BoomPower = Data.PropMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+ local Energy = ACF_Kinetic( Data.MuzzleVel*(39.37) , Data.ProjMass, Data.LimitVel )
+ GUIData.MaxPen = (Energy.Penetration/(Data.PenAera))*ACF.KEtoRHA
+ return GUIData
+end
+
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "APCR" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ --local FrAera = BulletData.FrAera
+ local DData = Round.getDisplayData(BulletData)
+
+ --fakeent.ACF.Armour = DData.MaxPen or 0
+ --fakepen.Penetration = (DData.MaxPen * FrAera) / ACF.KEtoRHA
+ --local fakepen = ACF_Kinetic( BulletData.SlugMV*39.37 , BulletData.SlugMass, 9999999 )
+ --local MaxHP = ACF_CalcDamage( fakeent , fakepen , FrAera , 0 )
+
+ --[[
+ local TotalMass = BulletData.ProjMass + BulletData.PropMass
+ local MassUnit
+
+ if TotalMass < 0.1 then
+ TotalMass = TotalMass * 1000
+ MassUnit = " g"
+ else
+ MassUnit = " kg"
+ end
+ ]]--
+
+ local str =
+ {
+ --"Cartridge Mass: ", math.Round(TotalMass, 2), MassUnit, "\n",
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm"
+ --"Max Pen. Damage: ", math.Round(MaxHP.Damage, 1), " HP\n",
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet.Filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet.Flight , Bullet.Filter , Energy.Kinetic*HitRes.Loss , Bullet.Caliber , Target.ACF.Armour , Bullet.Owner ) --Do some spalling
+ Bullet.Flight = Bullet.Flight:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet.ProjMass)^0.5 * 39.37
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+ else
+ table.insert( Bullet.Filter , Target )
+ return "Penetrated" end
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos )
+
+ ACF_RemoveBullet( Index )
+
+end
+
+-- Bullet stops here
+function Round.endeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Impact", Spall )
+
+end
+
+-- Bullet penetrated something
+function Round.pierceeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+end
+
+-- Bullet ricocheted off something
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.APCR )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Penetrator Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "APCR" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Penetrator Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m\\s") --Proj muzzle velocity (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+
+ acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+
+end
+
+list.Set( "ACFRoundTypes", "APCR", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "APCR" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundapds.lua b/lua/acf/shared/rounds/roundapds.lua
new file mode 100644
index 000000000..ccbc4bac2
--- /dev/null
+++ b/lua/acf/shared/rounds/roundapds.lua
@@ -0,0 +1,266 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.APDS = { "MO", "SL", "HW" , "SC", "MG" , "SB", "RAC", "GL", "HMG", "AAM", "ARTY", "ASM", "BOMB", "GBU", "POD", "SAM", "UAR", "FFAR", "FGL" }
+
+local Round = {}
+local PenMod = 1.5
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Armor Piercing, Discarding Sabot (APDS)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A subcaliber munition designed to trade damage for penetration. Loses energy quickly over distance."
+Round.netid = 10 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ Data.ProjMass = (Data.FrAera/5) * (Data.ProjLength*7.9/1000) --Volume of the projectile as a cylinder * density of steel
+ Data.ShovePower = 0.2
+ Data.PenAera = (Data.FrAera^ACF.PenAreaMod)/3
+ Data.DragCoef = ((Data.FrAera/20000)/Data.ProjMass)
+ Data.LimitVel = 800 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ Data.BoomPower = Data.PropMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+ local Energy = ACF_Kinetic( Data.MuzzleVel*(39.37) , Data.ProjMass, Data.LimitVel )
+ GUIData.MaxPen = (Energy.Penetration/(Data.PenAera))*ACF.KEtoRHA
+ return GUIData
+end
+
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "APDS" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ --local FrAera = BulletData.FrAera
+ local DData = Round.getDisplayData(BulletData)
+
+ --fakeent.ACF.Armour = DData.MaxPen or 0
+ --fakepen.Penetration = (DData.MaxPen * FrAera) / ACF.KEtoRHA
+ --local fakepen = ACF_Kinetic( BulletData.SlugMV*39.37 , BulletData.SlugMass, 9999999 )
+ --local MaxHP = ACF_CalcDamage( fakeent , fakepen , FrAera , 0 )
+
+ --[[
+ local TotalMass = BulletData.ProjMass + BulletData.PropMass
+ local MassUnit
+
+ if TotalMass < 0.1 then
+ TotalMass = TotalMass * 1000
+ MassUnit = " g"
+ else
+ MassUnit = " kg"
+ end
+ ]]--
+
+ local str =
+ {
+ --"Cartridge Mass: ", math.Round(TotalMass, 2), MassUnit, "\n",
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm"
+ --"Max Pen. Damage: ", math.Round(MaxHP.Damage, 1), " HP\n",
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet.Filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet.Flight , Bullet.Filter , Energy.Kinetic*HitRes.Loss , Bullet.Caliber , Target.ACF.Armour , Bullet.Owner ) --Do some spalling
+ Bullet.Flight = Bullet.Flight:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet.ProjMass)^0.5 * 39.37
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+ else
+ table.insert( Bullet.Filter , Target )
+ return "Penetrated" end
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos )
+
+ ACF_RemoveBullet( Index )
+
+end
+
+-- Bullet stops here
+function Round.endeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Impact", Spall )
+
+end
+
+-- Bullet penetrated something
+function Round.pierceeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+end
+
+-- Bullet ricocheted off something
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.APDS )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Penetrator Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "APDS" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Penetrator Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m\\s") --Proj muzzle velocity (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+
+ acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+
+end
+
+list.Set( "ACFRoundTypes", "APDS", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "APDS" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundapfsds.lua b/lua/acf/shared/rounds/roundapfsds.lua
new file mode 100644
index 000000000..f9f6fb354
--- /dev/null
+++ b/lua/acf/shared/rounds/roundapfsds.lua
@@ -0,0 +1,266 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.APFSDS = { "MO", "SL", "C" , "HW" , "AC", "SC" , "SA" , "MG" , "AL" , "RAC", "GL", "HMG", "AAM", "ARTY", "ASM", "BOMB", "GBU", "POD", "SAM", "UAR", "FFAR", "FGL" }
+
+local Round = {}
+local PenMod = 1.5
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "AP Fin Stabilized, Discarding Sabot (APFSDS)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A fin stabilized sabot munition designed to trade damage for superior penetration and long range effectiveness."
+Round.netid = 9 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ Data.ProjMass = (Data.FrAera/22) * (Data.ProjLength*7.9/1000) --Volume of the projectile as a cylinder * density of steel
+ Data.ShovePower = 0.2
+ Data.PenAera = (Data.FrAera^ACF.PenAreaMod)/8.5
+ Data.DragCoef = ((Data.FrAera/60000)/Data.ProjMass)
+ Data.LimitVel = 1000 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ Data.BoomPower = Data.PropMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+ local Energy = ACF_Kinetic( Data.MuzzleVel*(39.37) , Data.ProjMass, Data.LimitVel )
+ GUIData.MaxPen = (Energy.Penetration/(Data.PenAera))*ACF.KEtoRHA
+ return GUIData
+end
+
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "APFSDS" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ --local FrAera = BulletData.FrAera
+ local DData = Round.getDisplayData(BulletData)
+
+ --fakeent.ACF.Armour = DData.MaxPen or 0
+ --fakepen.Penetration = (DData.MaxPen * FrAera) / ACF.KEtoRHA
+ --local fakepen = ACF_Kinetic( BulletData.SlugMV*39.37 , BulletData.SlugMass, 9999999 )
+ --local MaxHP = ACF_CalcDamage( fakeent , fakepen , FrAera , 0 )
+
+ --[[
+ local TotalMass = BulletData.ProjMass + BulletData.PropMass
+ local MassUnit
+
+ if TotalMass < 0.1 then
+ TotalMass = TotalMass * 1000
+ MassUnit = " g"
+ else
+ MassUnit = " kg"
+ end
+ ]]--
+
+ local str =
+ {
+ --"Cartridge Mass: ", math.Round(TotalMass, 2), MassUnit, "\n",
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm"
+ --"Max Pen. Damage: ", math.Round(MaxHP.Damage, 1), " HP\n",
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet.Filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet.Flight , Bullet.Filter , Energy.Kinetic*HitRes.Loss , Bullet.Caliber , Target.ACF.Armour , Bullet.Owner ) --Do some spalling
+ Bullet.Flight = Bullet.Flight:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet.ProjMass)^0.5 * 39.37
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+ else
+ table.insert( Bullet.Filter , Target )
+ return "Penetrated" end
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos )
+
+ ACF_RemoveBullet( Index )
+
+end
+
+-- Bullet stops here
+function Round.endeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Impact", Spall )
+
+end
+
+-- Bullet penetrated something
+function Round.pierceeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+end
+
+-- Bullet ricocheted off something
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.APFSDS )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Penetrator Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "APFSDS" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength-80,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Penetrator Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m\\s") --Proj muzzle velocity (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+
+ acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+
+end
+
+list.Set( "ACFRoundTypes", "APFSDS", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "APFSDS" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundaphe.lua b/lua/acf/shared/rounds/roundaphe.lua
new file mode 100644
index 000000000..293729a90
--- /dev/null
+++ b/lua/acf/shared/rounds/roundaphe.lua
@@ -0,0 +1,272 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.APHE = { "MO", "MG", "RAC", "SL" }
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Armour Piercing Explosive (APHE)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "An armour piercing round with a cavity for High explosives. Less capable of defeating armour than plain Armour Piercing, but will explode after penetration"
+Round.netid = 5 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ PlayerData.Data5 = math.max(PlayerData.Data5 or 0, 0)
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ --Shell sturdiness calcs
+ Data.ProjMass = math.max(GUIData.ProjVolume-PlayerData.Data5,0)*7.9/1000 + math.min(PlayerData.Data5,GUIData.ProjVolume)*ACF.HEDensity/1000--Volume of the projectile as a cylinder - Volume of the filler * density of steel + Volume of the filler * density of TNT
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data.FrAera, Data.Caliber, Data.ProjLength )
+ GUIData.MinFillerVol = 0
+ GUIData.MaxFillerVol = math.min(GUIData.ProjVolume,MaxVol*0.9)
+ GUIData.FillerVol = math.min(PlayerData.Data5,GUIData.MaxFillerVol)
+ Data.FillerMass = GUIData.FillerVol * ACF.HEDensity/1000
+
+ Data.ProjMass = math.max(GUIData.ProjVolume-GUIData.FillerVol,0)*7.9/1000 + Data.FillerMass
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ --Random bullshit left
+ Data.ShovePower = 0.1
+ Data.PenAera = Data.FrAera^ACF.PenAreaMod
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 700 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 65 --Base ricochet angle
+
+ Data.BoomPower = Data.PropMass + Data.FillerMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+ GUIData.MaxPen = (Energy.Penetration/Data.PenAera)*ACF.KEtoRHA
+
+ GUIData.BlastRadius = (Data.FillerMass)^0.33*8
+ local FragMass = Data.ProjMass - Data.FillerMass
+ GUIData.Fragments = math.max(math.floor((Data.FillerMass/FragMass)*ACF.HEFrag),2)
+ GUIData.FragMass = FragMass/GUIData.Fragments
+ GUIData.FragVel = (Data.FillerMass*ACF.HEPower*1000/GUIData.FragMass/GUIData.Fragments)^0.5
+ return GUIData
+end
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "APHE" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "FillerMass", BulletData.FillerMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ local DData = Round.getDisplayData(BulletData)
+
+ local str =
+ {
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm\n",
+ "Blast Radius: ", math.Round(DData.BlastRadius, 1), " m\n",
+ "Blast Energy: ", math.floor((BulletData.FillerMass) * ACF.HEPower), " KJ"
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet.Filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet.Flight , Bullet.Filter , Energy.Kinetic*HitRes.Loss , Bullet.Caliber , Target.ACF.Armour , Bullet.Owner ) --Do some spalling
+ Bullet.Flight = Bullet.Flight:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet.ProjMass)^0.5 * 39.37
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+ else
+ table.insert( Bullet.Filter , Target )
+ return "Penetrated" end
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos, HitNormal )
+
+ ACF_HE( HitPos - Bullet.Flight:GetNormalized()*3, HitNormal, Bullet.FillerMass, Bullet.ProjMass - Bullet.FillerMass, Bullet.Owner, nil, Bullet.Gun )
+ ACF_RemoveBullet( Index )
+
+end
+
+function Round.endeffect( Effect, Bullet )
+
+ local Radius = (Bullet.FillerMass)^0.33*8*39.37
+ local Flash = EffectData()
+ Flash:SetOrigin( Bullet.SimPos )
+ Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
+ Flash:SetRadius( math.max( Radius, 1 ) )
+ util.Effect( "ACF_Scaled_Explosion", Flash )
+
+end
+
+function Round.pierceeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+end
+
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.APHE )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "HE Filler", "")--Hollow Point Cavity Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("PenetrationRanging", "") --penetration ranging (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "APHE" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "HE Filler Volume", "HE Filler Mass : "..(math.floor(Data.FillerMass*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA") --Proj muzzle penetration (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/100).." m") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+
+ acfmenupanel:CPanelText("PenetrationRanging", "\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+end
+
+list.Set( "ACFRoundTypes", "APHE", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "APHE" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundfl.lua b/lua/acf/shared/rounds/roundfl.lua
new file mode 100644
index 000000000..a0125fc91
--- /dev/null
+++ b/lua/acf/shared/rounds/roundfl.lua
@@ -0,0 +1,336 @@
+AddCSLuaFile()
+
+ACF.AmmoBlacklist["FL"] = { "AC", "RAC", "MG", "HMG", "GL", "SL" }
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Flechette (FL)" --Human readable name
+Round.model = "models/munitions/dart_100mm.mdl" --Shell flight model
+Round.desc = "Flechette rounds contain several long thin steel spikes, functioning as a shotgun shell for cannons. While it seems like the spikes would penetrate well, they tend to tumble in flight and impact at less than ideal angles, causing only minor penetration and structural damage. They are best used against infantry or lightly armored mobile targets such as aircraft or light tanks, since flechettes trade brute damage for a better chance to hit."
+Round.netid = 8 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ --setup flechettes
+ local FlechetteData = {}
+ FlechetteData["Caliber"] = math.Round( BulletData["FlechetteRadius"]*0.2 ,2)
+ FlechetteData["Id"] = BulletData["Id"]
+ FlechetteData["Type"] = "AP" --BulletData["Type"]
+ FlechetteData["Owner"] = BulletData["Owner"]
+ FlechetteData["Crate"] = BulletData["Crate"]
+ FlechetteData["Gun"] = BulletData["Gun"]
+ FlechetteData["Pos"] = BulletData["Pos"]
+ FlechetteData["FrAera"] = BulletData["FlechetteArea"]
+ FlechetteData["ProjMass"] = BulletData["FlechetteMass"]
+ FlechetteData["DragCoef"] = BulletData["FlechetteDragCoef"]
+ FlechetteData["Tracer"] = BulletData["Tracer"]
+ FlechetteData["LimitVel"] = BulletData["LimitVel"]
+ FlechetteData["Ricochet"] = BulletData["Ricochet"]
+ FlechetteData["PenAera"] = BulletData["FlechettePenArea"]
+ FlechetteData["ShovePower"] = BulletData["ShovePower"]
+ FlechetteData["KETransfert"] = BulletData["KETransfert"]
+
+ local I=1
+ local MuzzleVec
+
+ if Gun:GetClass() == "acf_ammo" then --if ammo is cooking off, shoot in random direction
+ local Inaccuracy
+ MuzzleVec = VectorRand()
+ for I = 1, BulletData["Flechettes"] do
+ Inaccuracy = VectorRand() / 360 * ((Gun.Inaccuracy or 0) + BulletData["FlechetteSpread"])
+ FlechetteData["Flight"] = (MuzzleVec+Inaccuracy):GetNormalized() * BulletData["MuzzleVel"] * 39.37 + Gun:GetVelocity()
+ ACF_CreateBullet( FlechetteData )
+ end
+ else
+ local BaseInaccuracy = math.tan(math.rad(Gun:GetInaccuracy()))
+ local AddInaccuracy = math.tan(math.rad(BulletData["FlechetteSpread"]))
+ MuzzleVec = Gun:GetForward()
+ for I = 1, BulletData["Flechettes"] do
+ BaseSpread = BaseInaccuracy * (math.random() ^ (1 / math.Clamp(ACF.GunInaccuracyBias, 0.5, 4))) * (Gun:GetUp() * (2 * math.random() - 1) + Gun:GetRight() * (2 * math.random() - 1)):GetNormalized()
+ AddSpread = AddInaccuracy * (math.random() ^ (1 / math.Clamp(ACF.GunInaccuracyBias, 0.5, 4))) * (Gun:GetUp() * (2 * math.random() - 1) + Gun:GetRight() * (2 * math.random() - 1)):GetNormalized()
+ FlechetteData["Flight"] = (MuzzleVec+BaseSpread+AddSpread):GetNormalized() * BulletData["MuzzleVel"] * 39.37 + Gun:GetVelocity()
+ ACF_CreateBullet( FlechetteData )
+ end
+ end
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ Data["LengthAdj"] = 0.5
+ if not PlayerData["PropLength"] then PlayerData["PropLength"] = 0 end
+ if not PlayerData["ProjLength"] then PlayerData["ProjLength"] = 0 end
+ if not PlayerData["Data5"] then PlayerData["Data5"] = 3 end --flechette count
+ if not PlayerData["Data6"] then PlayerData["Data6"] = 5 end --flechette spread
+ if not PlayerData["Data10"] then PlayerData["Data10"] = 0 end --tracer
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ local GunClass = ACF.Weapons["Guns"][(Data["Id"] or PlayerData["Id"])]["gunclass"]
+ if GunClass == "SA" then
+ Data["MaxFlechettes"] = math.Clamp(math.floor(Data["Caliber"]*3-4.5),1,32)
+ elseif GunClass == "MO" then
+ Data["MaxFlechettes"] = math.Clamp(math.floor(Data["Caliber"]*4)-12,1,32)
+ elseif GunClass == "HW" then
+ Data["MaxFlechettes"] = math.Clamp(math.floor(Data["Caliber"]*4)-10,1,32)
+ else
+ Data["MaxFlechettes"] = math.Clamp(math.floor(Data["Caliber"]*4)-8,1,32)
+ end
+ Data["MinFlechettes"] = math.min(6,Data["MaxFlechettes"]) --force bigger guns to have higher min count
+ Data["Flechettes"] = math.Clamp(math.floor(PlayerData["Data5"]),Data["MinFlechettes"], Data["MaxFlechettes"]) --number of flechettes
+
+ Data["MinSpread"] = 0.25
+ Data["MaxSpread"] = 30
+ Data["FlechetteSpread"] = math.Clamp(tonumber(PlayerData["Data6"]), Data["MinSpread"], Data["MaxSpread"])
+
+ local PenAdj = 0.8 --higher means lower pen, but more structure (hp) damage (old: 2.35, 2.85)
+ local RadiusAdj = 1.0 -- lower means less structure (hp) damage, but higher pen (old: 1.0, 0.8)
+ local PackRatio = 0.0025*Data["Flechettes"]+0.69 --how efficiently flechettes are packed into shell
+ Data["FlechetteRadius"] = math.sqrt( ( (PackRatio*RadiusAdj*Data["Caliber"]/2)^2 ) / Data["Flechettes"] ) -- max radius flechette can be, to fit number of flechettes in a shell
+ Data["FlechetteArea"] = 3.1416 * Data["FlechetteRadius"]^2 -- area of a single flechette
+ Data["FlechetteMass"] = Data["FlechetteArea"] * (Data["ProjLength"]*7.9/1000) -- volume of single flechette * density of steel
+ Data["FlechettePenArea"] = (PenAdj*Data["FlechetteArea"])^ACF.PenAreaMod
+ Data["FlechetteDragCoef"] = (Data["FlechetteArea"]/10000)/Data["FlechetteMass"]
+
+ Data["ProjMass"] = Data["Flechettes"] * Data["FlechetteMass"] -- total mass of all flechettes
+ Data["PropMass"] = Data["PropMass"]
+ Data["ShovePower"] = 0.2
+ Data["PenAera"] = Data["FrAera"]^ACF.PenAreaMod
+ Data["DragCoef"] = ((Data["FrAera"]/10000)/Data["ProjMass"])
+ Data["LimitVel"] = 500 --Most efficient penetration speed in m/s
+ Data["KETransfert"] = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data["Ricochet"] = 75 --Base ricochet angle
+ Data["MuzzleVel"] = ACF_MuzzleVelocity( Data["PropMass"], Data["ProjMass"], Data["Caliber"] )
+
+ Data["BoomPower"] = Data["PropMass"]
+
+ if SERVER then --Only the crates need this part
+ ServerData["Id"] = PlayerData["Id"]
+ ServerData["Type"] = PlayerData["Type"]
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only the GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data, PlayerData))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+function Round.getDisplayData(Data, PlayerData)
+ local GUIData = {}
+ local Energy = ACF_Kinetic( Data["MuzzleVel"]*39.37 , Data["FlechetteMass"], Data["LimitVel"] )
+ GUIData["MaxPen"] = (Energy.Penetration/Data["FlechettePenArea"])*ACF.KEtoRHA
+ return GUIData
+end
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString("AmmoType","FL")
+ Crate:SetNWString("AmmoID",BulletData["Id"])
+ Crate:SetNWFloat("PropMass",BulletData["PropMass"])
+ Crate:SetNWFloat("MuzzleVel",BulletData["MuzzleVel"])
+ Crate:SetNWFloat("Tracer",BulletData["Tracer"])
+ -- bullet effects use networked data, so set these to the flechette stats
+ Crate:SetNWFloat("Caliber",math.Round( BulletData["FlechetteRadius"]*0.2 ,2))
+ Crate:SetNWFloat("ProjMass",BulletData["FlechetteMass"])
+ Crate:SetNWFloat("DragCoef",BulletData["FlechetteDragCoef"])
+ Crate:SetNWFloat( "FillerMass", 0 )
+ --Crate:SetNWFloat("Caliber",BulletData["Caliber"])
+ --Crate:SetNWFloat("ProjMass",BulletData["ProjMass"])
+ --Crate:SetNWFloat("DragCoef",BulletData["DragCoef"])
+
+end
+
+function Round.cratetxt( BulletData )
+
+ local DData = Round.getDisplayData(BulletData)
+
+ local inaccuracy = 0
+ local Gun = list.Get("ACFEnts").Guns[BulletData.Id]
+
+ if Gun then
+ local Classes = list.Get("ACFClasses")
+ inaccuracy = (Classes.GunClass[Gun.gunclass] or {spread = 0}).spread
+ end
+
+ local coneAng = inaccuracy * ACF.GunInaccuracyScale
+
+ local str =
+ {
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm\n",
+ "Max Spread: ", math.ceil((BulletData.FlechetteSpread + coneAng) * 10) / 10, " deg"
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ local Speed = Bullet["Flight"]:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet["ProjMass"], Bullet["LimitVel"] )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet["Filter"] , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet["Flight"] , Bullet["Filter"] , Energy.Kinetic*HitRes.Loss , Bullet["Caliber"] , Target.ACF.Armour , Bullet["Owner"] ) --Do some spalling
+ Bullet["Flight"] = Bullet["Flight"]:GetNormalized() * (Energy.Kinetic*(1-HitRes.Loss)*2000/Bullet["ProjMass"])^0.5 * 39.37
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+ else
+ table.insert( Bullet["Filter"] , Target )
+ return "Penetrated" end
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, Bullet.LimitVel )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ elseif HitRes.Ricochet then
+ return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos )
+
+ ACF_RemoveBullet( Index )
+
+end
+
+-- Bullet stops here
+function Round.endeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Impact", Spall )
+
+end
+
+-- Bullet penetrated something
+function Round.pierceeffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+end
+
+-- Bullet ricocheted off something
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist["FL"] )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("Flechettes",3,3,32,0, "Flechettes", "") --flechette count Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FlechetteSpread",10,5,60,1, "Flechette Spread", "") --flechette spread Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI
+ PlayerData["Type"] = "FL" --Hardcoded, match ACFRoundTypes table index
+ PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider
+ PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider
+ PlayerData["Data5"] = acfmenupanel.AmmoData["Flechettes"] --Flechette count slider
+ PlayerData["Data6"] = acfmenupanel.AmmoData["FlechetteSpread"] --flechette spread slider
+ --PlayerData["Data7"] = acfmenupanel.AmmoData[Name] --Not used
+ --PlayerData["Data8"] = acfmenupanel.AmmoData[Name] --Not used
+ --PlayerData["Data9"] = acfmenupanel.AmmoData[Name] --Not used
+ local Tracer = 0
+ if acfmenupanel.AmmoData["Tracer"] then Tracer = 1 end
+ PlayerData["Data10"] = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData["Data"]["id"] )
+ RunConsoleCommand( "acfmenu_data2", PlayerData["Type"] )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data5", Data.Flechettes )
+ RunConsoleCommand( "acfmenu_data6", Data.FlechetteSpread )
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data["MaxTotalLength"],3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data["MaxTotalLength"],3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("Flechettes",Data.Flechettes,Data.MinFlechettes,Data.MaxFlechettes,0, "Flechettes", "Flechette Radius: "..math.Round(Data["FlechetteRadius"]*10,2).." mm")
+ acfmenupanel:AmmoSlider("FlechetteSpread",Data.FlechetteSpread,Data.MinSpread,Data.MaxSpread,1, "Flechette Spread", "")
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData["Type"]]["desc"]) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m\\s") --Proj muzzle velocity (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.FlechetteDragCoef, Data.FlechetteMass, Data.FlechettePenArea, Data.LimitVel, 300 )
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.FlechetteDragCoef, Data.FlechetteMass, Data.FlechettePenArea, Data.LimitVel, 800 )
+
+ acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+end
+
+list.Set( "ACFRoundTypes", "FL", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid , "FL" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundfunctions.lua b/lua/acf/shared/rounds/roundfunctions.lua
new file mode 100644
index 000000000..2c3eaff90
--- /dev/null
+++ b/lua/acf/shared/rounds/roundfunctions.lua
@@ -0,0 +1,66 @@
+AddCSLuaFile( "acf/shared/rounds/roundfunctions.lua" )
+
+function ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ local BulletMax = ACF.Weapons["Guns"][PlayerData["Id"]]["round"]
+ GUIData["MaxTotalLength"] = BulletMax["maxlength"] * (Data["LengthAdj"] or 1)
+
+ Data["Caliber"] = ACF.Weapons["Guns"][PlayerData["Id"]]["caliber"]
+ Data["FrAera"] = 3.1416 * (Data["Caliber"]/2)^2
+
+ Data["Tracer"] = 0
+ if PlayerData["Data10"]*1 > 0 then --Check for tracer
+ Data["Tracer"] = math.min(5/Data["Caliber"],2.5) --Tracer space calcs
+ end
+
+ local PropMax = (BulletMax["propweight"]*1000/ACF.PDensity) / Data["FrAera"] --Current casing absolute max propellant capacity
+ local CurLength = (PlayerData["ProjLength"] + math.min(PlayerData["PropLength"],PropMax) + Data["Tracer"])
+ GUIData["MinPropLength"] = 0.01
+ GUIData["MaxPropLength"] = math.max(math.min(GUIData["MaxTotalLength"]-CurLength+PlayerData["PropLength"], PropMax),GUIData["MinPropLength"]) --Check if the desired prop lenght fits in the case and doesn't exceed the gun max
+
+ GUIData["MinProjLength"] = Data["Caliber"]*1.5
+ GUIData["MaxProjLength"] = math.max(GUIData["MaxTotalLength"]-CurLength+PlayerData["ProjLength"],GUIData["MinProjLength"]) --Check if the desired proj lenght fits in the case
+
+ local Ratio = math.min( (GUIData["MaxTotalLength"] - Data["Tracer"])/(PlayerData["ProjLength"] + math.min(PlayerData["PropLength"],PropMax)) , 1 ) --This is to check the current ratio between elements if i need to clamp it
+ Data["ProjLength"] = math.Clamp(PlayerData["ProjLength"]*Ratio,GUIData["MinProjLength"],GUIData["MaxProjLength"])
+ Data["PropLength"] = math.Clamp(PlayerData["PropLength"]*Ratio,GUIData["MinPropLength"],GUIData["MaxPropLength"])
+
+ Data["PropMass"] = Data["FrAera"] * (Data["PropLength"]*ACF.PDensity/1000) --Volume of the case as a cylinder * Powder density converted from g to kg
+ GUIData["ProjVolume"] = Data["FrAera"] * Data["ProjLength"]
+ Data["RoundVolume"] = Data["FrAera"] * (Data["ProjLength"] + Data["PropLength"])
+
+ return PlayerData, Data, ServerData, GUIData
+end
+
+function ACF_RoundShellCapacity( Momentum, FrAera, Caliber, ProjLength )
+ local MinWall = 0.2+((Momentum/FrAera)^0.7)/50 --The minimal shell wall thickness required to survive firing at the current energy level
+ local Length = math.max(ProjLength-MinWall,0)
+ local Radius = math.max((Caliber/2)-MinWall,0)
+ local Volume = 3.1416*Radius^2 * Length
+ return Volume, Length, Radius --Returning the cavity volume and the minimum wall thickness
+end
+
+function ACF_RicoProbability( Rico, Speed)
+ local MinAngle = math.min(Rico - Speed/15,89)
+ return { Min = math.Round(math.max(MinAngle,0.1),1), Mean = math.Round(math.max(MinAngle+(90-MinAngle)/2,0.1),1), Max = 90 }
+end
+
+--Formula from https://mathscinotes.wordpress.com/2013/10/03/parameter-determination-for-pejsa-velocity-model/
+--not terribly accurate for acf, particularly small caliber (7.62mm off by 120 m/s at 800m), but is good enough for quick indicator
+function ACF_PenRanging( MuzzleVel, DragCoef, ProjMass, PenAera, LimitVel, Range ) --range in m, vel is m/s
+ local V0 = (MuzzleVel * 39.37 * ACF.VelScale) --initial velocity
+ local D0 = (DragCoef * V0^2 / ACF.DragDiv) --initial drag
+ local K1 = ( D0 / (V0^(3/2)) )^-1 --estimated drag coefficient
+
+ local Vel = (math.sqrt(V0) - ((Range*39.37) / (2 * K1)) )^2
+ local Pen = (ACF_Kinetic( Vel, ProjMass, LimitVel ).Penetration/PenAera)*ACF.KEtoRHA
+
+ return (Vel*0.0254), Pen
+end
+
+function ACF_CalcCrateStats( CrateVol, RoundVol )
+ local CapMul = (CrateVol > 40250) and ((math.log(CrateVol*0.00066)/math.log(2)-4)*0.15+1) or 1
+ local RoFMul = (CrateVol > 40250) and (1-(math.log(CrateVol*0.00066)/math.log(2)-4)*0.05) or 1
+ local Cap = math.floor(CapMul * CrateVol * ACF.AmmoMod * ACF.CrateVolEff * 16.38 / RoundVol)
+ return Cap, CapMul, RoFMul
+end
diff --git a/lua/acf/shared/rounds/roundhe.lua b/lua/acf/shared/rounds/roundhe.lua
new file mode 100644
index 000000000..060f8e13a
--- /dev/null
+++ b/lua/acf/shared/rounds/roundhe.lua
@@ -0,0 +1,253 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.HE = { "MG", "RAC", "SL" }
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "High Explosive (HE)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A shell filled with explosives, detonating on impact"
+Round.netid = 2 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ PlayerData.Data5 = math.max(PlayerData.Data5 or 0, 0)
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ --Shell sturdiness calcs
+ Data.ProjMass = math.max(GUIData.ProjVolume-PlayerData.Data5,0)*7.9/1000 + math.min(PlayerData.Data5,GUIData.ProjVolume)*ACF.HEDensity/1000--Volume of the projectile as a cylinder - Volume of the filler * density of steel + Volume of the filler * density of TNT
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data.FrAera, Data.Caliber, Data.ProjLength )
+ GUIData.MinFillerVol = 0
+ GUIData.MaxFillerVol = math.min(GUIData.ProjVolume,MaxVol)
+ GUIData.FillerVol = math.min(PlayerData.Data5,GUIData.MaxFillerVol)
+ Data.FillerMass = GUIData.FillerVol * ACF.HEDensity/1000
+
+ Data.ProjMass = math.max(GUIData.ProjVolume-GUIData.FillerVol,0)*7.9/1000 + Data.FillerMass
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ --Random bullshit left
+ Data.ShovePower = 0.1
+ Data.PenAera = Data.FrAera^ACF.PenAreaMod
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 100 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.DetonatorAngle = 80
+
+ Data.BoomPower = Data.PropMass + Data.FillerMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+ GUIData.BlastRadius = (Data.FillerMass)^0.33*8
+ local FragMass = Data.ProjMass - Data.FillerMass
+ GUIData.Fragments = math.max(math.floor((Data.FillerMass/FragMass)*ACF.HEFrag),2)
+ GUIData.FragMass = FragMass/GUIData.Fragments
+ GUIData.FragVel = (Data.FillerMass*ACF.HEPower*1000/GUIData.FragMass/GUIData.Fragments)^0.5
+ return GUIData
+end
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "HE" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "FillerMass", BulletData.FillerMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ local DData = Round.getDisplayData(BulletData)
+
+ local str =
+ {
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Blast Radius: ", math.Round(DData.BlastRadius, 1), " m\n",
+ "Blast Energy: ", math.floor((BulletData.FillerMass) * ACF.HEPower), " KJ"
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass - Bullet.FillerMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+ if HitRes.Ricochet then
+ return "Ricochet"
+ end
+ end
+ return false
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ return false
+
+end
+
+function Round.endflight( Index, Bullet, HitPos, HitNormal )
+
+ ACF_HE( HitPos - Bullet.Flight:GetNormalized()*3, HitNormal, Bullet.FillerMass, Bullet.ProjMass - Bullet.FillerMass, Bullet.Owner, nil, Bullet.Gun )
+ ACF_RemoveBullet( Index )
+
+end
+
+function Round.endeffect( Effect, Bullet )
+
+ local Radius = (Bullet.FillerMass)^0.33*8*39.37
+ local Flash = EffectData()
+ Flash:SetOrigin( Bullet.SimPos )
+ Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
+ Flash:SetRadius( math.max( Radius, 1 ) )
+ util.Effect( "ACF_Scaled_Explosion", Flash )
+
+end
+
+function Round.pierceeffect( Effect, Bullet )
+
+ local BulletEffect = {}
+ BulletEffect.Num = 1
+ BulletEffect.Src = Bullet.SimPos - Bullet.SimFlight:GetNormalized()
+ BulletEffect.Dir = Bullet.SimFlight:GetNormalized()
+ BulletEffect.Spread = Vector(0,0,0)
+ BulletEffect.Tracer = 0
+ BulletEffect.Force = 0
+ BulletEffect.Damage = 0
+ LocalPlayer():FireBullets(BulletEffect)
+
+ util.Decal("ExplosiveGunshot", Bullet.SimPos + Bullet.SimFlight*10, Bullet.SimPos - Bullet.SimFlight*10)
+
+ local Spall = EffectData()
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( math.max(((Bullet.RoundMass * (Bullet.SimFlight:Length()/39.37)^2)/2000)/10000,1) )
+ util.Effect( "AP_Hit", Spall )
+
+end
+
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( Bullet.SimFlight:GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect(ACF.AmmoBlacklist.HE)
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "HE Filler", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "HE" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "HE Filler Volume", "HE Filler Mass : "..(math.floor(Data.FillerMass*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/100).." m") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+end
+
+list.Set( "ACFRoundTypes", "HE", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "HE" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundheat.lua b/lua/acf/shared/rounds/roundheat.lua
new file mode 100644
index 000000000..113da50b1
--- /dev/null
+++ b/lua/acf/shared/rounds/roundheat.lua
@@ -0,0 +1,438 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.HEAT = { "MG", "HMG", "RAC", "AC", "SL" , "SB" }
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "High Explosive Anti-Tank (HEAT)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A shell with a shaped charge. When the round detonates, the explosive energy is focused into driving a small molten metal penetrator into the victim with extreme force, though this results in reduced damage from the explosion itself. Multiple layers of armor will dissipate the penetrator quickly."
+Round.netid = 4 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+function Round.ConeCalc( ConeAngle, Radius, Length )
+
+ local ConeLength = math.tan(math.rad(ConeAngle))*Radius
+ local ConeAera = 3.1416 * Radius * (Radius^2 + ConeLength^2)^0.5
+ local ConeVol = (3.1416 * Radius^2 * ConeLength)/3
+
+ return ConeLength, ConeAera, ConeVol
+
+end
+
+-- calculates conversion of filler from powering HEAT jet to raw HE based on crush vel
+-- above a threshold vel, HEAT jet doesn't have time to form properly, converting to raw HE proportionally
+-- Vel needs to be in m/s (gmu*0.0254)
+function Round.CrushCalc( Vel, FillerMass )
+ local Crushed = math.Clamp( (Vel - ACF.HEATMinCrush) / (ACF.HEATMaxCrush - ACF.HEATMinCrush), 0,1)
+ local HE_Filler = Lerp(Crushed, FillerMass*ACF.HEATBoomConvert, FillerMass)
+ local HEAT_Filler = Lerp(Crushed, FillerMass, 0)
+ --local HE_Filler = FillerMass * ACF.HEATBoomConvert + Crushed * FillerMass * (1-ACF.HEATBoomConvert)
+ --local HEAT_Filler = (1-Crushed) * FillerMass
+ return Crushed, HEAT_Filler, HE_Filler
+end
+
+-- coneang now required for slug recalculation at detonation, defaults to 55 if not present
+function Round.CalcSlugMV( Data, HEATFillerMass )
+ --keep fillermass/2 so that penetrator stays the same.
+ return ( HEATFillerMass/2 * ACF.HEPower * math.sin(math.rad(10+(Data.ConeAng or 55))/2) /Data.SlugMass)^ACF.HEATMVScale
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ PlayerData.Data5 = math.max(PlayerData.Data5 or 0, 0)
+ if not PlayerData.Data6 then PlayerData.Data6 = 0 end
+ if not PlayerData.Data7 then PlayerData.Data7 = 0 end
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ local ConeThick = Data.Caliber/50
+ local ConeLength = 0
+ local ConeAera = 0
+ local AirVol = 0
+ ConeLength, ConeAera, AirVol = Round.ConeCalc( PlayerData.Data6, Data.Caliber/2, PlayerData.ProjLength )
+ Data.ProjMass = math.max(GUIData.ProjVolume-PlayerData.Data5,0)*7.9/1000 + math.min(PlayerData.Data5,GUIData.ProjVolume)*ACF.HEDensity/1000 + ConeAera*ConeThick*7.9/1000 --Volume of the projectile as a cylinder - Volume of the filler - Volume of the crush cone * density of steel + Volume of the filler * density of TNT + Aera of the cone * thickness * density of steel
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ local MaxVol = 0
+ local MaxLength = 0
+ local MaxRadius = 0
+ MaxVol, MaxLength, MaxRadius = ACF_RoundShellCapacity( Energy.Momentum, Data.FrAera, Data.Caliber, Data.ProjLength )
+
+ GUIData.MinConeAng = 0
+ GUIData.MaxConeAng = math.deg( math.atan((Data.ProjLength - ConeThick )/(Data.Caliber/2)) )
+ Data.ConeAng = math.Clamp(PlayerData.Data6*1, GUIData.MinConeAng, GUIData.MaxConeAng)
+ ConeLength, ConeAera, AirVol = Round.ConeCalc( Data.ConeAng, Data.Caliber/2, Data.ProjLength )
+ local ConeVol = ConeAera * ConeThick
+
+ GUIData.MinFillerVol = 0
+ GUIData.MaxFillerVol = math.max(MaxVol - AirVol - ConeVol,GUIData.MinFillerVol)
+ GUIData.FillerVol = math.Clamp(PlayerData.Data5*1,GUIData.MinFillerVol,GUIData.MaxFillerVol)
+
+ -- fillermass used for shell mass calcs
+ -- heatfillermass is how much fillermass is used to power heat jet
+ -- boomfillermass is how much fillermass creates HE damage on detonation. technically get 1/3 extra fillermass free as HE with no crushing, but screw trying to rebalance heat pen to properly use 1/3 of filler for HE and 2/3 for jet
+ -- distribution of heat and boom fillermass is calculated at detonation, or for GUI stuff
+
+ Data.FillerMass = GUIData.FillerVol * ACF.HEDensity/1450
+ Data.ProjMass = math.max(GUIData.ProjVolume-GUIData.FillerVol- AirVol-ConeVol,0)*7.9/1000 + Data.FillerMass + ConeVol*7.9/1000
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ --Let's calculate the actual HEAT slug
+ Data.SlugMass = ConeVol*7.9/1000
+ local Rad = math.rad(Data.ConeAng/2)
+ Data.SlugCaliber = Data.Caliber - Data.Caliber * (math.sin(Rad)*0.5+math.cos(Rad)*1.5)/2
+
+ local SlugFrAera = 3.1416 * (Data.SlugCaliber/2)^2
+ Data.SlugPenAera = SlugFrAera^ACF.PenAreaMod
+ Data.SlugDragCoef = ((SlugFrAera/10000)/Data.SlugMass)
+ Data.SlugRicochet = 500 --Base ricochet angle (The HEAT slug shouldn't ricochet at all)
+
+ -- these are only for compatibility with other stuff. it's recalculated when the round is detonated
+ local crush, heatfiller, boomfiller = Round.CrushCalc(Data.MuzzleVel, Data.FillerMass)
+ Data.BoomFillerMass = boomfiller
+ Data.SlugMV = Round.CalcSlugMV( Data, heatfiller )
+
+ --Random bullshit left
+ Data.CasingMass = Data.ProjMass - Data.FillerMass - ConeVol*7.9/1000
+ Data.ShovePower = 0.1
+ Data.PenAera = Data.FrAera^ACF.PenAreaMod
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 100 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.DetonatorAngle = 75
+
+ Data.Detonated = false
+ Data.NotFirstPen = false
+ Data.BoomPower = Data.PropMass + Data.FillerMass -- for when a crate is cooking off
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only the GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data, GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+
+ -- these are only GUI info, it's recalculated when the round is detonated since it's vel dependent
+ GUIData.Crushed, GUIData.HEATFillerMass, GUIData.BoomFillerMass = Round.CrushCalc(Data.MuzzleVel, Data.FillerMass)
+ GUIData.SlugMV = Round.CalcSlugMV( Data, GUIData.HEATFillerMass ) * (Data.SlugPenMul or 1) -- slugpenmul is a missiles thing
+ GUIData.SlugMassUsed = Data.SlugMass * (1-GUIData.Crushed)
+
+ local SlugEnergy = ACF_Kinetic( Data.MuzzleVel*39.37 + GUIData.SlugMV*39.37 ,GUIData.SlugMassUsed , 999999 )
+ GUIData.MaxPen = (SlugEnergy.Penetration/Data.SlugPenAera)*ACF.KEtoRHA
+
+ GUIData.TotalFragMass = Data.CasingMass + Data.SlugMass * GUIData.Crushed
+ GUIData.BlastRadius = (GUIData.BoomFillerMass)^0.33*8--*39.37
+ GUIData.Fragments = math.max(math.floor((GUIData.BoomFillerMass/GUIData.TotalFragMass)*ACF.HEFrag),2)
+ GUIData.FragMass = GUIData.TotalFragMass / GUIData.Fragments
+ GUIData.FragVel = (GUIData.BoomFillerMass*ACF.HEPower*1000/GUIData.TotalFragMass)^0.5
+
+ return GUIData
+end
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "HEAT" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "FillerMass", BulletData.FillerMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "SlugMass", BulletData.SlugMass )
+ Crate:SetNWFloat( "SlugCaliber", BulletData.SlugCaliber )
+ Crate:SetNWFloat( "SlugDragCoef", BulletData.SlugDragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+
+--local fakeent = {ACF = {Armour = 0}}
+--local fakepen = {Penetration = 999999999}
+function Round.cratetxt( BulletData, builtFullData )
+
+ local DData = Round.getDisplayData(BulletData)
+
+ local str =
+ {
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm\n",
+ "Blast Radius: ", math.Round(DData.BlastRadius, 1), " m\n",
+ "Blast Energy: ", math.floor((DData.BoomFillerMass) * ACF.HEPower), " KJ"
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.detonate( Index, Bullet, HitPos, HitNormal )
+
+ local Crushed, HEATFillerMass, BoomFillerMass = Round.CrushCalc(Bullet.Flight:Length()*0.0254, Bullet.FillerMass)
+
+ ACF_HE( HitPos - Bullet.Flight:GetNormalized()*3, HitNormal, BoomFillerMass, Bullet.CasingMass + Bullet.SlugMass * Crushed, Bullet.Owner, nil, Bullet.Gun )
+
+ if Crushed == 1 then return false end -- no HEAT jet to fire off, it was all converted to HE
+
+ local SlugMV = Round.CalcSlugMV( Bullet, HEATFillerMass )
+
+ Bullet.Detonated = true
+ Bullet.InitTime = SysTime()
+ Bullet.Flight = Bullet.Flight + Bullet.Flight:GetNormalized() * Round.CalcSlugMV( Bullet, HEATFillerMass ) * 39.37
+ Bullet.FuseLength = 0.005 + 40/(Bullet.Flight:Length()*0.0254)
+ Bullet.Pos = HitPos
+ Bullet.DragCoef = Bullet.SlugDragCoef
+ Bullet.ProjMass = Bullet.SlugMass * (1-Crushed)
+ Bullet.Caliber = Bullet.SlugCaliber
+ Bullet.PenAera = Bullet.SlugPenAera
+ Bullet.Ricochet = Bullet.SlugRicochet
+
+ local DeltaTime = SysTime() - Bullet.LastThink
+ Bullet.StartTrace = Bullet.Pos - Bullet.Flight:GetNormalized()*math.min(ACF.PhysMaxVel*DeltaTime,Bullet.FlightTime*Bullet.Flight:Length())
+ Bullet.NextPos = Bullet.Pos + (Bullet.Flight * ACF.VelScale * DeltaTime) --Calculates the next shell position
+
+ return true
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ if Bullet.Detonated then
+ Bullet.NotFirstPen = true
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass, 999999 )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet.Filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet.Flight , Bullet.Filter , Energy.Kinetic*HitRes.Loss , Bullet.Caliber , Target.ACF.Armour , Bullet.Owner ) --Do some spalling
+ Bullet.Flight = Bullet.Flight:GetNormalized() * math.sqrt(Energy.Kinetic * (1 - HitRes.Loss) * ((Bullet.NotFirstPen and ACF.HEATPenLayerMul) or 1) * 2000 / Bullet.ProjMass) * 39.37
+
+ return "Penetrated"
+ else
+ return false
+ end
+
+ else
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass - Bullet.FillerMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Ricochet then
+ return "Ricochet"
+ else
+ local jet = Round.detonate( Index, Bullet, HitPos, HitNormal )
+ if jet then
+ return "Penetrated"
+ else
+ return false
+ end
+ end
+
+ end
+ else
+ table.insert( Bullet.Filter , Target )
+ return "Penetrated"
+ end
+
+ return false
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ if not Bullet.Detonated then
+ local jet = Round.detonate( Index, Bullet, HitPos, HitNormal )
+ if jet then
+ return "Penetrated"
+ else
+ return false
+ end
+ end
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, 999999 )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ --elseif HitRes.Ricochet then --penetrator won't ricochet
+ -- return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos, HitNormal )
+
+ ACF_RemoveBullet( Index )
+
+end
+
+function Round.endeffect( Effect, Bullet )
+
+ local Impact = EffectData()
+ Impact:SetEntity( Bullet.Crate )
+ Impact:SetOrigin( Bullet.SimPos )
+ Impact:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Impact:SetScale( Bullet.SimFlight:Length() )
+ Impact:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Impact", Impact )
+
+end
+
+function Round.pierceeffect( Effect, Bullet )
+
+ if Bullet.Detonated then
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+ else
+
+ local Crushed, HEATFillerMass, BoomFillerMass = Round.CrushCalc(Bullet.SimFlight:Length()*0.0254, Bullet.FillerMass)
+ local Radius = (BoomFillerMass)^0.33*8*39.37
+ local Flash = EffectData()
+ Flash:SetOrigin( Bullet.SimPos )
+ Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
+ Flash:SetRadius( math.max( Radius, 1 ) )
+ util.Effect( "ACF_HEAT_Explosion", Flash )
+
+ Bullet.Detonated = true
+ Effect:SetModel("models/Gibs/wood_gib01e.mdl")
+
+ end
+
+end
+
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Gun )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.HEAT )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "")
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "")
+ acfmenupanel:AmmoSlider("ConeAng",0,0,1000,3, "HEAT Cone Angle", "")
+ acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "Total HEAT Warhead volume", "")
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
+
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("SlugDisplay", "") --HEAT Slug data (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "HEAT" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol
+ PlayerData.Data6 = acfmenupanel.AmmoData.ConeAng
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength )
+ RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
+ RunConsoleCommand( "acfmenu_data6", Data.ConeAng )
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ConeAng",Data.ConeAng,Data.MinConeAng,Data.MaxConeAng,0, "Crush Cone Angle", "") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "HE Filler Volume", "HE Filler Mass : "..(math.floor(Data.FillerMass*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/100).." m") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ R1P = (ACF_Kinetic( (R1V + Data.SlugMV) * 39.37, Data.SlugMassUsed, 999999 ).Penetration/Data.SlugPenAera)*ACF.KEtoRHA
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+ R2P = (ACF_Kinetic( (R2V + Data.SlugMV) * 39.37, Data.SlugMassUsed, 999999 ).Penetration/Data.SlugPenAera)*ACF.KEtoRHA
+
+ acfmenupanel:CPanelText("SlugDisplay", "Penetrator Mass : "..(math.floor(Data.SlugMassUsed*10000)/10).." g \n Penetrator Caliber : "..(math.floor(Data.SlugCaliber*100)/10).." mm \n Penetrator Velocity : "..math.floor(Data.MuzzleVel + Data.SlugMV).." m/s \n Penetrator Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+end
+
+list.Set( "ACFRoundTypes", "HEAT", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "HEAT" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundheatfs.lua b/lua/acf/shared/rounds/roundheatfs.lua
new file mode 100644
index 000000000..f0793f7ae
--- /dev/null
+++ b/lua/acf/shared/rounds/roundheatfs.lua
@@ -0,0 +1,440 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.HEATFS = { "MO", "SL", "C" , "HW" , "AC", "SC" , "SA" , "MG" , "AL" , "RAC", "GL", "HMG", "AAM", "ARTY", "ASM", "BOMB", "GBU", "POD", "SAM", "UAR", "FFAR", "FGL" }
+
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "High Explosive Anti-Tank Fin Stabilized (HEAT-FS)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "HEAT, but fin stabilized with a fixed minimum propellant charge. Smoothbores only."
+Round.netid = 11 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+function Round.ConeCalc( ConeAngle, Radius, Length )
+
+ local ConeLength = math.tan(math.rad(ConeAngle))*Radius
+ local ConeAera = 3.1416 * Radius * (Radius^2 + ConeLength^2)^0.5
+ local ConeVol = (3.1416 * Radius^2 * ConeLength)/3
+
+ return ConeLength, ConeAera, ConeVol
+
+end
+
+-- calculates conversion of filler from powering HEAT jet to raw HE based on crush vel
+-- above a threshold vel, HEAT jet doesn't have time to form properly, converting to raw HE proportionally
+-- Vel needs to be in m/s (gmu*0.0254)
+function Round.CrushCalc( Vel, FillerMass )
+ local Crushed = math.Clamp( (Vel - ACF.HEATMinCrush) / (ACF.HEATMaxCrush - ACF.HEATMinCrush), 0,1)
+ local HE_Filler = Lerp(Crushed, FillerMass*ACF.HEATBoomConvert, FillerMass)
+ local HEAT_Filler = Lerp(Crushed, FillerMass, 0)
+ --local HE_Filler = FillerMass * ACF.HEATBoomConvert + Crushed * FillerMass * (1-ACF.HEATBoomConvert)
+ --local HEAT_Filler = (1-Crushed) * FillerMass
+ return Crushed, HEAT_Filler, HE_Filler
+end
+
+-- coneang now required for slug recalculation at detonation, defaults to 55 if not present
+function Round.CalcSlugMV( Data, HEATFillerMass )
+ --keep fillermass/2 so that penetrator stays the same.
+ return ( HEATFillerMass/2 * ACF.HEPower * math.sin(math.rad(10+(Data.ConeAng or 55))/2) /Data.SlugMass)^ACF.HEATMVScale
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ if not PlayerData.PropLength then PlayerData.PropLength = Data.Caliber*3.75 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ --PlayerData.PropLength = math.min(PlayerData.PropLength, PlayerData.ProjLength *2)
+ PlayerData.Data5 = math.max(PlayerData.Data5 or 0, 0)
+ if not PlayerData.Data6 then PlayerData.Data6 = 0 end
+ if not PlayerData.Data7 then PlayerData.Data7 = 0 end
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ local ConeThick = Data.Caliber/50
+ local ConeLength = 0
+ local ConeAera = 0
+ local AirVol = 0
+ ConeLength, ConeAera, AirVol = Round.ConeCalc( PlayerData.Data6, Data.Caliber/2, PlayerData.ProjLength )
+ Data.ProjMass = math.max(GUIData.ProjVolume-PlayerData.Data5,0)*7.9/1000 + math.min(PlayerData.Data5,GUIData.ProjVolume)*ACF.HEDensity/1000 + ConeAera*ConeThick*7.9/1000 --Volume of the projectile as a cylinder - Volume of the filler - Volume of the crush cone * density of steel + Volume of the filler * density of TNT + Aera of the cone * thickness * density of steel
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ local MaxVol = 0
+ local MaxLength = 0
+ local MaxRadius = 0
+ MaxVol, MaxLength, MaxRadius = ACF_RoundShellCapacity( Energy.Momentum, Data.FrAera, Data.Caliber, Data.ProjLength )
+
+ GUIData.MinConeAng = 0
+ GUIData.MaxConeAng = math.deg( math.atan((Data.ProjLength - ConeThick )/(Data.Caliber/2)) )
+ Data.ConeAng = math.Clamp(PlayerData.Data6*1, GUIData.MinConeAng, GUIData.MaxConeAng)
+ ConeLength, ConeAera, AirVol = Round.ConeCalc( Data.ConeAng, Data.Caliber/2, Data.ProjLength )
+ local ConeVol = ConeAera * ConeThick
+
+ GUIData.MinFillerVol = 0
+ GUIData.MaxFillerVol = math.max(MaxVol - AirVol - ConeVol,GUIData.MinFillerVol)
+ GUIData.FillerVol = math.Clamp(PlayerData.Data5*1,GUIData.MinFillerVol,GUIData.MaxFillerVol)
+
+ -- fillermass used for shell mass calcs
+ -- heatfillermass is how much fillermass is used to power heat jet
+ -- boomfillermass is how much fillermass creates HE damage on detonation. technically get 1/3 extra fillermass free as HE with no crushing, but screw trying to rebalance heat pen to properly use 1/3 of filler for HE and 2/3 for jet
+ -- distribution of heat and boom fillermass is calculated at detonation, or for GUI stuff
+
+ Data.FillerMass = GUIData.FillerVol * ACF.HEDensity/1450
+ Data.ProjMass = math.max(GUIData.ProjVolume-GUIData.FillerVol- AirVol-ConeVol,0)*7.9/1000 + Data.FillerMass + ConeVol*7.9/1000
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ --Let's calculate the actual HEAT slug
+ Data.SlugMass = ConeVol*7.9/1000
+ local Rad = math.rad(Data.ConeAng/2)
+ Data.SlugCaliber = Data.Caliber - Data.Caliber * (math.sin(Rad)*0.5+math.cos(Rad)*1.5)/2
+
+ local SlugFrAera = 3.1416 * (Data.SlugCaliber/2)^2
+ Data.SlugPenAera = (SlugFrAera^ACF.PenAreaMod)/1.25
+ Data.SlugDragCoef = ((SlugFrAera/10000)/Data.SlugMass)
+ Data.SlugRicochet = 500 --Base ricochet angle (The HEAT slug shouldn't ricochet at all)
+
+ -- these are only for compatibility with other stuff. it's recalculated when the round is detonated
+ local crush, heatfiller, boomfiller = Round.CrushCalc(Data.MuzzleVel, Data.FillerMass)
+ Data.BoomFillerMass = boomfiller
+ Data.SlugMV = Round.CalcSlugMV( Data, heatfiller )
+
+ --Random bullshit left
+ Data.CasingMass = Data.ProjMass - Data.FillerMass - ConeVol*7.9/1000
+ Data.ShovePower = 0.1
+ Data.PenAera = (Data.FrAera^ACF.PenAreaMod)
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 100 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.DetonatorAngle = 75
+
+ Data.Detonated = false
+ Data.NotFirstPen = false
+ Data.BoomPower = Data.PropMass + Data.FillerMass -- for when a crate is cooking off
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only the GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data, GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+
+ -- these are only GUI info, it's recalculated when the round is detonated since it's vel dependent
+ GUIData.Crushed, GUIData.HEATFillerMass, GUIData.BoomFillerMass = Round.CrushCalc(Data.MuzzleVel, Data.FillerMass)
+ GUIData.SlugMV = Round.CalcSlugMV( Data, GUIData.HEATFillerMass ) * (Data.SlugPenMul or 1) -- slugpenmul is a missiles thing
+ GUIData.SlugMassUsed = Data.SlugMass * (1-GUIData.Crushed)
+
+ local SlugEnergy = ACF_Kinetic( Data.MuzzleVel*39.37 + GUIData.SlugMV*39.37 ,GUIData.SlugMassUsed , 999999 )
+ GUIData.MaxPen = (SlugEnergy.Penetration/Data.SlugPenAera)*ACF.KEtoRHA
+
+ GUIData.TotalFragMass = Data.CasingMass + Data.SlugMass * GUIData.Crushed
+ GUIData.BlastRadius = (GUIData.BoomFillerMass)^0.33*8--*39.37
+ GUIData.Fragments = math.max(math.floor((GUIData.BoomFillerMass/GUIData.TotalFragMass)*ACF.HEFrag),2)
+ GUIData.FragMass = GUIData.TotalFragMass / GUIData.Fragments
+ GUIData.FragVel = (GUIData.BoomFillerMass*ACF.HEPower*1000/GUIData.TotalFragMass)^0.5
+
+ return GUIData
+end
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "HEATFS" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "FillerMass", BulletData.FillerMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "SlugMass", BulletData.SlugMass )
+ Crate:SetNWFloat( "SlugCaliber", BulletData.SlugCaliber )
+ Crate:SetNWFloat( "SlugDragCoef", BulletData.SlugDragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+
+--local fakeent = {ACF = {Armour = 0}}
+--local fakepen = {Penetration = 999999999}
+function Round.cratetxt( BulletData, builtFullData )
+
+ local DData = Round.getDisplayData(BulletData)
+
+ local str =
+ {
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm\n",
+ "Blast Radius: ", math.Round(DData.BlastRadius, 1), " m\n",
+ "Blast Energy: ", math.floor((DData.BoomFillerMass) * ACF.HEPower), " KJ"
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.detonate( Index, Bullet, HitPos, HitNormal )
+
+ local Crushed, HEATFillerMass, BoomFillerMass = Round.CrushCalc(Bullet.Flight:Length()*0.0254, Bullet.FillerMass)
+
+ ACF_HE( HitPos - Bullet.Flight:GetNormalized()*3, HitNormal, BoomFillerMass, Bullet.CasingMass + Bullet.SlugMass * Crushed, Bullet.Owner, nil, Bullet.Gun )
+
+ if Crushed == 1 then return false end -- no HEAT jet to fire off, it was all converted to HE
+
+ local SlugMV = Round.CalcSlugMV( Bullet, HEATFillerMass )
+
+ Bullet.Detonated = true
+ Bullet.InitTime = SysTime()
+ Bullet.Flight = Bullet.Flight + Bullet.Flight:GetNormalized() * Round.CalcSlugMV( Bullet, HEATFillerMass ) * 39.37
+ Bullet.FuseLength = 0.005 + 40/(Bullet.Flight:Length()*0.0254)
+ Bullet.Pos = HitPos
+ Bullet.DragCoef = Bullet.SlugDragCoef
+ Bullet.ProjMass = Bullet.SlugMass * (1-Crushed)
+ Bullet.Caliber = Bullet.SlugCaliber
+ Bullet.PenAera = Bullet.SlugPenAera
+ Bullet.Ricochet = Bullet.SlugRicochet
+
+ local DeltaTime = SysTime() - Bullet.LastThink
+ Bullet.StartTrace = Bullet.Pos - Bullet.Flight:GetNormalized()*math.min(ACF.PhysMaxVel*DeltaTime,Bullet.FlightTime*Bullet.Flight:Length())
+ Bullet.NextPos = Bullet.Pos + (Bullet.Flight * ACF.VelScale * DeltaTime) --Calculates the next shell position
+
+ return true
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+
+ if Bullet.Detonated then
+ Bullet.NotFirstPen = true
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass, 999999 )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Overkill > 0 then
+ table.insert( Bullet.Filter , Target ) --"Penetrate" (Ingoring the prop for the retry trace)
+ ACF_Spall( HitPos , Bullet.Flight , Bullet.Filter , Energy.Kinetic*HitRes.Loss , Bullet.Caliber , Target.ACF.Armour , Bullet.Owner ) --Do some spalling
+ Bullet.Flight = Bullet.Flight:GetNormalized() * math.sqrt(Energy.Kinetic * (1 - HitRes.Loss) * ((Bullet.NotFirstPen and ACF.HEATPenLayerMul) or 1) * 2000 / Bullet.ProjMass) * 39.37
+
+ return "Penetrated"
+ else
+ return false
+ end
+
+ else
+
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass - Bullet.FillerMass, Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+
+ if HitRes.Ricochet then
+ return "Ricochet"
+ else
+ local jet = Round.detonate( Index, Bullet, HitPos, HitNormal )
+ if jet then
+ return "Penetrated"
+ else
+ return false
+ end
+ end
+
+ end
+ else
+ table.insert( Bullet.Filter , Target )
+ return "Penetrated"
+ end
+
+ return false
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ if not Bullet.Detonated then
+ local jet = Round.detonate( Index, Bullet, HitPos, HitNormal )
+ if jet then
+ return "Penetrated"
+ else
+ return false
+ end
+ end
+
+ local Energy = ACF_Kinetic( Bullet.Flight:Length() / ACF.VelScale, Bullet.ProjMass, 999999 )
+ local HitRes = ACF_PenetrateGround( Bullet, Energy, HitPos, HitNormal )
+ if HitRes.Penetrated then
+ return "Penetrated"
+ --elseif HitRes.Ricochet then --penetrator won't ricochet
+ -- return "Ricochet"
+ else
+ return false
+ end
+
+end
+
+function Round.endflight( Index, Bullet, HitPos, HitNormal )
+
+ ACF_RemoveBullet( Index )
+
+end
+
+function Round.endeffect( Effect, Bullet )
+
+ local Impact = EffectData()
+ Impact:SetEntity( Bullet.Crate )
+ Impact:SetOrigin( Bullet.SimPos )
+ Impact:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Impact:SetScale( Bullet.SimFlight:Length() )
+ Impact:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Impact", Impact )
+
+end
+
+function Round.pierceeffect( Effect, Bullet )
+
+ if Bullet.Detonated then
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Crate )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Penetration", Spall )
+
+ else
+
+ local Crushed, HEATFillerMass, BoomFillerMass = Round.CrushCalc(Bullet.SimFlight:Length()*0.0254, Bullet.FillerMass)
+ local Radius = (BoomFillerMass)^0.33*8*39.37
+ local Flash = EffectData()
+ Flash:SetOrigin( Bullet.SimPos )
+ Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
+ Flash:SetRadius( math.max( Radius, 1 ) )
+ util.Effect( "ACF_HEAT_Explosion", Flash )
+
+ Bullet.Detonated = true
+ Effect:SetModel("models/Gibs/wood_gib01e.mdl")
+
+ end
+
+end
+
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Gun )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.HEATFS )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "")
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "")
+ acfmenupanel:AmmoSlider("ConeAng",0,0,1000,3, "HEAT Cone Angle", "")
+ acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "Total HEAT Warhead volume", "")
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
+
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("SlugDisplay", "") --HEAT Slug data (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "HEATFS" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol
+ PlayerData.Data6 = acfmenupanel.AmmoData.ConeAng
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength )
+ RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
+ RunConsoleCommand( "acfmenu_data6", Data.ConeAng )
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength+(Data.Caliber*3.75),Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ConeAng",Data.ConeAng,Data.MinConeAng,Data.MaxConeAng,0, "Crush Cone Angle", "") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "HE Filler Volume", "HE Filler Mass : "..(math.floor(Data.FillerMass*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/100).." m") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ R1P = (ACF_Kinetic( (R1V + Data.SlugMV) * 39.37, Data.SlugMassUsed, 999999 ).Penetration/Data.SlugPenAera)*ACF.KEtoRHA
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+ R2P = (ACF_Kinetic( (R2V + Data.SlugMV) * 39.37, Data.SlugMassUsed, 999999 ).Penetration/Data.SlugPenAera)*ACF.KEtoRHA
+
+ acfmenupanel:CPanelText("SlugDisplay", "Penetrator Mass : "..(math.floor(Data.SlugMassUsed*10000)/10).." g \n Penetrator Caliber : "..(math.floor(Data.SlugCaliber*100)/10).." mm \n Penetrator Velocity : "..math.floor(Data.MuzzleVel + Data.SlugMV).." m/s \n Penetrator Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+end
+
+list.Set( "ACFRoundTypes", "HEATFS", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "HEATFS" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundhp.lua b/lua/acf/shared/rounds/roundhp.lua
new file mode 100644
index 000000000..b2e0d5efc
--- /dev/null
+++ b/lua/acf/shared/rounds/roundhp.lua
@@ -0,0 +1,181 @@
+
+AddCSLuaFile()
+
+local RoundTypes = list.Get( "ACFRoundTypes" )
+local Round = RoundTypes.AP -- inherit from AP
+
+ACF.AmmoBlacklist.HP = ACF.AmmoBlacklist.AP
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Hollow Point (HP)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A solid shell with a soft point, meant to flatten against armour"
+Round.netid = 3 --Unique ammotype ID for network transmission
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ PlayerData.Data5 = math.max(PlayerData.Data5 or 0, 0)
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ --if GUIData.MaxCavVol != nil then PlayerData.Data5 = math.min(PlayerData.Data5, GUIData.MaxCavVol) end
+
+ --Shell sturdiness calcs
+ Data.ProjMass = math.max(GUIData.ProjVolume*0.5,0)*7.9/1000 --(Volume of the projectile as a cylinder - Volume of the cavity) * density of steel
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data.FrAera, Data.Caliber, Data.ProjLength )
+ GUIData.MinCavVol = 0
+ GUIData.MaxCavVol = math.min(GUIData.ProjVolume,MaxVol)
+ Data.CavVol = math.Clamp(PlayerData.Data5,GUIData.MinCavVol,GUIData.MaxCavVol)
+
+ Data.ProjMass = ( (Data.FrAera * Data.ProjLength) - Data.CavVol )*7.9/1000 --Volume of the projectile as a cylinder * fraction missing due to hollow point (Data5) * density of steel
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ local ExpRatio = (Data.CavVol/GUIData.ProjVolume)
+ Data.ShovePower = 0.2 + ExpRatio/2
+ Data.ExpCaliber = Data.Caliber + ExpRatio*Data.ProjLength
+ Data.PenAera = (3.1416 * Data.ExpCaliber/2)^2^ACF.PenAreaMod
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 400 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 90 --Base ricochet angle
+
+ Data.BoomPower = Data.PropMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+
+function Round.getDisplayData(Data)
+ local GUIData = {}
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+ GUIData.MaxKETransfert = Energy.Kinetic*Data.ShovePower
+ GUIData.MaxPen = (Energy.Penetration/Data.PenAera)*ACF.KEtoRHA
+ return GUIData
+end
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "HP" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "ExpCaliber", BulletData.ExpCaliber )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ local DData = Round.getDisplayData(BulletData)
+
+ local str =
+ {
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s\n",
+ "Max Penetration: ", math.floor(DData.MaxPen), " mm\n",
+ "Expanded Caliber: ", math.floor(BulletData.ExpCaliber * 10), " mm\n",
+ "Imparted Energy: ", math.floor(DData.MaxKETransfert), " KJ"
+ }
+
+ return table.concat(str)
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.HP )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Propellant Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Projectile Length Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("CavVol",0,0,1000,2, "Hollow Point Length", "")--Hollow Point Cavity Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("KEDisplay", "") --Proj muzzle KE (Name, Desc)
+ --acfmenupanel:CPanelText("RicoDisplay", "") --estimated rico chance
+ acfmenupanel:CPanelText("PenetrationDisplay", "") --Proj muzzle penetration (Name, Desc)
+
+ Round.guiupdate( Panel, nil )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "HP" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ PlayerData.Data5 = acfmenupanel.AmmoData.CavVol
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data5", Data.CavVol )
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoSlider("CavVol",Data.CavVol,Data.MinCavVol,Data.MaxCavVol,2, "Hollow Point cavity Volume", "Expanded caliber : "..(math.floor(Data.ExpCaliber*10)).." mm")--Hollow Point Cavity Slider (Name, Min, Max, Decimals, Title, Desc)
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("KEDisplay", "Kinetic Energy Transfered : "..math.floor(Data.MaxKETransfert).." KJ") --Proj muzzle KE (Name, Desc)
+
+ --local RicoAngs = ACF_RicoProbability( Data.Ricochet, Data.MuzzleVel*ACF.VelScale )
+ --acfmenupanel:CPanelText("RicoDisplay", "Ricochet probability vs impact angle:\n".." 0% @ "..RicoAngs.Min.." degrees\n 50% @ "..RicoAngs.Mean.." degrees\n100% @ "..RicoAngs.Max.." degrees")
+
+ local R1V, R1P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 300 )
+ local R2V, R2P = ACF_PenRanging( Data.MuzzleVel, Data.DragCoef, Data.ProjMass, Data.PenAera, Data.LimitVel, 800 )
+
+ acfmenupanel:CPanelText("PenetrationDisplay", "Maximum Penetration : "..math.floor(Data.MaxPen).." mm RHA\n\n300m pen: "..math.Round(R1P,0).."mm @ "..math.Round(R1V,0).." m\\s\n800m pen: "..math.Round(R2P,0).."mm @ "..math.Round(R2V,0).." m\\s\n\nThe range data is an approximation and may not be entirely accurate.") --Proj muzzle penetration (Name, Desc)
+
+end
+
+list.Set( "ACFRoundTypes", "HP", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "HP" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/acf/shared/rounds/roundrefill.lua b/lua/acf/shared/rounds/roundrefill.lua
new file mode 100644
index 000000000..df7474492
--- /dev/null
+++ b/lua/acf/shared/rounds/roundrefill.lua
@@ -0,0 +1,74 @@
+
+AddCSLuaFile()
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Refill" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "Ammo Refill"
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local BulletData = {}
+ BulletData.Id = PlayerData.Id or "12.7mmMG"
+ BulletData.Type = PlayerData.Type or "AP"
+
+ BulletData.Caliber = ACF.Weapons.Guns[PlayerData.Id].caliber
+ BulletData.ProjMass = 2*7.9/100 --Volume of the projectile as a cylinder * streamline factor (Data5) * density of steel
+ BulletData.PropMass = 2*ACF.PDensity/1000 --Volume of the case as a cylinder * Powder density converted from g to kg
+ BulletData.FillerMass = BulletData.FillerMass or 0
+ BulletData.DragCoef = BulletData.DragCoef or 0
+ BulletData.Tracer = BulletData.Tracer or 0
+ BulletData.MuzzleVel = BulletData.MuzzleVel or 0
+ BulletData.RoundVolume = 1
+
+ return BulletData
+
+end
+
+
+function Round.getDisplayData(Data)
+ return {}
+end
+
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "Refill" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "FillerMass", BulletData.FillerMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.cratetxt( BulletData )
+
+ return ""
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect()
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.CData.AmmoId )
+ RunConsoleCommand( "acfmenu_data2", "Refill")
+
+ acfmenupanel.CustomDisplay:PerformLayout()
+
+end
+
+list.Set( "ACFRoundTypes", "Refill", Round ) --Set the round properties
diff --git a/lua/acf/shared/rounds/roundsmoke.lua b/lua/acf/shared/rounds/roundsmoke.lua
new file mode 100644
index 000000000..ff6cab4d7
--- /dev/null
+++ b/lua/acf/shared/rounds/roundsmoke.lua
@@ -0,0 +1,315 @@
+
+AddCSLuaFile()
+
+ACF.AmmoBlacklist.SM = { "MG", "C", "GL", "HMG", "AL", "AC", "RAC", "SA", "SC" }
+
+local Round = {}
+
+Round.type = "Ammo" --Tells the spawn menu what entity to spawn
+Round.name = "Smoke (SM)" --Human readable name
+Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model
+Round.desc = "A shell filled white phosporous, detonating on impact. Smoke filler produces a long lasting cloud but takes a while to be effective, whereas WP filler quickly creates a cloud that also dissipates quickly. \n\n Can only be used in the 40mm Smoke Launcher"
+Round.netid = 6 --Unique ammotype ID for network transmission
+
+function Round.create( Gun, BulletData )
+
+ ACF_CreateBullet( BulletData )
+
+end
+
+-- Function to convert the player's slider data into the complete round data
+function Round.convert( Crate, PlayerData )
+
+ local Data = {}
+ local ServerData = {}
+ local GUIData = {}
+
+ if not PlayerData.PropLength then PlayerData.PropLength = 0 end
+ if not PlayerData.ProjLength then PlayerData.ProjLength = 0 end
+ PlayerData.Data5 = math.max(PlayerData.Data5 or 0, 0)
+ PlayerData.Data6 = math.max(PlayerData.Data6 or 0, 0)
+ PlayerData.Data7 = tonumber(PlayerData.Data7) or 0 --catching some possible errors with string data in legacy dupes
+ if not PlayerData.Data10 then PlayerData.Data10 = 0 end
+
+ PlayerData, Data, ServerData, GUIData = ACF_RoundBaseGunpowder( PlayerData, Data, ServerData, GUIData )
+
+ --Shell sturdiness calcs
+ Data.ProjMass = math.max(GUIData.ProjVolume-PlayerData.Data5,0)*7.9/1000 + math.min(PlayerData.Data5,GUIData.ProjVolume)*ACF.HEDensity/2000--Volume of the projectile as a cylinder - Volume of the filler * density of steel + Volume of the filler * density of TNT
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+ local Energy = ACF_Kinetic( Data.MuzzleVel*39.37 , Data.ProjMass, Data.LimitVel )
+
+ local MaxVol = ACF_RoundShellCapacity( Energy.Momentum, Data.FrAera, Data.Caliber, Data.ProjLength )
+ GUIData.MinFillerVol = 0
+ GUIData.MaxFillerVol = math.min(GUIData.ProjVolume,MaxVol)
+
+ GUIData.MaxSmokeVol = math.max(GUIData.MaxFillerVol-PlayerData.Data6,GUIData.MinFillerVol)
+ GUIData.MaxWPVol = math.max(GUIData.MaxFillerVol-PlayerData.Data5,GUIData.MinFillerVol)
+
+ local Ratio = math.min( GUIData.MaxFillerVol/(PlayerData.Data5 + PlayerData.Data6), 1 )
+ GUIData.FillerVol = math.min(PlayerData.Data5*Ratio,GUIData.MaxSmokeVol)
+ GUIData.WPVol = math.min(PlayerData.Data6*Ratio,GUIData.MaxWPVol)
+
+ Data.FillerMass = GUIData.FillerVol * ACF.HEDensity/2000
+ Data.WPMass = GUIData.WPVol * ACF.HEDensity/2000
+
+ Data.ProjMass = math.max(GUIData.ProjVolume-(GUIData.FillerVol+GUIData.WPVol),0)*7.9/1000 + Data.FillerMass + Data.WPMass
+ Data.MuzzleVel = ACF_MuzzleVelocity( Data.PropMass, Data.ProjMass, Data.Caliber )
+
+ --Random bullshit left
+ Data.ShovePower = 0.1
+ Data.PenAera = Data.FrAera^ACF.PenAreaMod
+ Data.DragCoef = ((Data.FrAera/10000)/Data.ProjMass)
+ Data.LimitVel = 100 --Most efficient penetration speed in m/s
+ Data.KETransfert = 0.1 --Kinetic energy transfert to the target for movement purposes
+ Data.Ricochet = 60 --Base ricochet angle
+ Data.DetonatorAngle = 80
+
+ if PlayerData.Data7 < 0.5 then
+ PlayerData.Data7 = 0
+ Data.FuseLength = PlayerData.Data7
+ else
+ PlayerData.Data7 = math.max(math.Round(PlayerData.Data7,1),0.5)
+ Data.FuseLength = PlayerData.Data7
+ end
+
+ Data.BoomPower = Data.PropMass + Data.FillerMass + Data.WPMass
+
+ if SERVER then --Only the crates need this part
+ ServerData.Id = PlayerData.Id
+ ServerData.Type = PlayerData.Type
+ return table.Merge(Data,ServerData)
+ end
+
+ if CLIENT then --Only tthe GUI needs this part
+ GUIData = table.Merge(GUIData, Round.getDisplayData(Data))
+ return table.Merge(Data,GUIData)
+ end
+
+end
+
+function Round.network( Crate, BulletData )
+
+ Crate:SetNWString( "AmmoType", "SM" )
+ Crate:SetNWString( "AmmoID", BulletData.Id )
+ Crate:SetNWFloat( "Caliber", BulletData.Caliber )
+ Crate:SetNWFloat( "ProjMass", BulletData.ProjMass )
+ Crate:SetNWFloat( "FillerMass", BulletData.FillerMass )
+ Crate:SetNWFloat( "WPMass", BulletData.WPMass )
+ Crate:SetNWFloat( "PropMass", BulletData.PropMass )
+ Crate:SetNWFloat( "DragCoef", BulletData.DragCoef )
+ Crate:SetNWFloat( "MuzzleVel", BulletData.MuzzleVel )
+ Crate:SetNWFloat( "Tracer", BulletData.Tracer )
+
+end
+
+function Round.getDisplayData(Data)
+
+ local GUIData = {}
+
+ GUIData.SMFiller = math.min(math.log(1+Data.FillerMass*8*39.37)/0.02303,350) --smoke filler
+ GUIData.SMLife = math.Round(20+GUIData.SMFiller/4,1)
+ GUIData.SMRadiusMin = math.Round(GUIData.SMFiller*1.25*0.15*0.0254,1)
+ GUIData.SMRadiusMax = math.Round(GUIData.SMFiller*1.25*2*0.0254,1)
+
+ GUIData.WPFiller = math.min(math.log(1+Data.WPMass*8*39.37)/0.02303,350) --wp filler
+ GUIData.WPLife = math.Round(6+GUIData.WPFiller/10,1)
+ GUIData.WPRadiusMin = math.Round(GUIData.WPFiller*1.25*0.0254,1)
+ GUIData.WPRadiusMax = math.Round(GUIData.WPFiller*1.25*2*0.0254,1)
+
+ return GUIData
+
+end
+
+function Round.cratetxt( BulletData )
+
+ local GUIData = Round.getDisplayData(BulletData)
+
+ local str = {
+ "Muzzle Velocity: ", math.Round(BulletData.MuzzleVel, 1), " m/s"
+ }
+
+ if GUIData.WPFiller > 0 then
+ local temp = {
+ "\nWP Radius: ", GUIData.WPRadiusMin, " m to ", GUIData.WPRadiusMax, " m\n",
+ "WP Lifetime: ", GUIData.WPLife, " s"
+ }
+
+ for i=1,#temp do
+ str[#str+1] = temp[i]
+ end
+ end
+
+ if GUIData.SMFiller > 0 then
+ local temp = {
+ "\nSM Radius: ", GUIData.SMRadiusMin, " m to ", GUIData.SMRadiusMax, " m\n",
+ "SM Lifetime: ", GUIData.SMLife, " s"
+ }
+
+ for i=1,#temp do
+ str[#str+1] = temp[i]
+ end
+ end
+
+ if BulletData.FuseLength > 0 then
+ local temp = {
+ "\nFuse time: ", BulletData.FuseLength, " s"
+ }
+
+ for i=1,#temp do
+ str[#str+1] = temp[i]
+ end
+ end
+
+ return table.concat(str)
+
+end
+
+function Round.propimpact( Index, Bullet, Target, HitNormal, HitPos, Bone )
+
+ if ACF_Check( Target ) then
+ local Speed = Bullet.Flight:Length() / ACF.VelScale
+ local Energy = ACF_Kinetic( Speed , Bullet.ProjMass - (Bullet.FillerMass + Bullet.WPMass), Bullet.LimitVel )
+ local HitRes = ACF_RoundImpact( Bullet, Speed, Energy, Target, HitPos, HitNormal , Bone )
+ if HitRes.Ricochet then
+ return "Ricochet"
+ end
+ end
+ return false
+
+end
+
+function Round.worldimpact( Index, Bullet, HitPos, HitNormal )
+
+ return false
+
+end
+
+function Round.endflight( Index, Bullet, HitPos, HitNormal )
+
+ --ACF_HE( HitPos - Bullet.Flight:GetNormalized()*3 , HitNormal, Bullet.FillerMass, Bullet.ProjMass - Bullet.FillerMass, Bullet.Owner )
+ ACF_RemoveBullet( Index )
+
+end
+
+function Round.endeffect( Effect, Bullet )
+
+ local Flash = EffectData()
+ Flash:SetOrigin( Bullet.SimPos )
+ Flash:SetNormal( Bullet.SimFlight:GetNormalized() )
+ Flash:SetRadius( math.max( Bullet.FillerMass*8*39.37, 0 ) ) --(Bullet.FillerMass)^0.33*8*39.37
+ Flash:SetMagnitude( math.max( Bullet.WPMass*8*39.37, 0 ) )
+
+ local vec = Vector(255,255,255)
+ if IsValid(Bullet.Crate) then vec = Bullet.Crate:GetNWVector( "TracerColour", Bullet.Crate:GetColor() ) end
+ Flash:SetStart(vec)
+ util.Effect( "ACF_Smoke", Flash )
+
+end
+
+function Round.pierceeffect( Effect, Bullet )
+
+ local BulletEffect = {}
+ BulletEffect.Num = 1
+ BulletEffect.Src = Bullet.SimPos - Bullet.SimFlight:GetNormalized()
+ BulletEffect.Dir = Bullet.SimFlight:GetNormalized()
+ BulletEffect.Spread = Vector(0,0,0)
+ BulletEffect.Tracer = 0
+ BulletEffect.Force = 0
+ BulletEffect.Damage = 0
+ LocalPlayer():FireBullets(BulletEffect)
+
+ util.Decal("ExplosiveGunshot", Bullet.SimPos + Bullet.SimFlight*10, Bullet.SimPos - Bullet.SimFlight*10)
+
+ local Spall = EffectData()
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( math.max(((Bullet.RoundMass * (Bullet.SimFlight:Length()/39.37)^2)/2000)/10000,1) )
+ util.Effect( "AP_Hit", Spall )
+
+end
+
+function Round.ricocheteffect( Effect, Bullet )
+
+ local Spall = EffectData()
+ Spall:SetEntity( Bullet.Gun )
+ Spall:SetOrigin( Bullet.SimPos )
+ Spall:SetNormal( (Bullet.SimFlight):GetNormalized() )
+ Spall:SetScale( Bullet.SimFlight:Length() )
+ Spall:SetMagnitude( Bullet.RoundMass )
+ util.Effect( "ACF_AP_Ricochet", Spall )
+
+end
+
+function Round.guicreate( Panel, Table )
+
+ acfmenupanel:AmmoSelect( ACF.AmmoBlacklist.SM )
+
+ acfmenupanel:CPanelText("BonusDisplay", "")
+
+ acfmenupanel:CPanelText("Desc", "") --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "") --Total round length (Name, Desc)
+
+ acfmenupanel:AmmoSlider("PropLength",0,0,1000,3, "Propellant Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",0,0,1000,3, "Projectile Length", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",0,0,1000,3, "Smoke Filler", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("WPVol",0,0,1000,3, "WP Filler", "") --Slider (Name, Value, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FuseLength",0,0,1000,3, "Timed Fuse", "")
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer", "") --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("VelocityDisplay", "") --Proj muzzle velocity (Name, Desc)
+ acfmenupanel:CPanelText("BlastDisplay", "") --HE Blast data (Name, Desc)
+ acfmenupanel:CPanelText("FragDisplay", "") --HE Fragmentation data (Name, Desc)
+
+ Round.guiupdate( Panel, Table )
+
+end
+
+function Round.guiupdate( Panel, Table )
+
+ local PlayerData = {}
+ PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI
+ PlayerData.Type = "SM" --Hardcoded, match ACFRoundTypes table index
+ PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider
+ PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider
+ PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol
+ PlayerData.Data6 = acfmenupanel.AmmoData.WPVol
+ PlayerData.Data7 = acfmenupanel.AmmoData.FuseLength
+ local Tracer = 0
+ if acfmenupanel.AmmoData.Tracer then Tracer = 1 end
+ PlayerData.Data10 = Tracer --Tracer
+
+ local Data = Round.convert( Panel, PlayerData )
+
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.AmmoData.Data.id )
+ RunConsoleCommand( "acfmenu_data2", PlayerData.Type )
+ RunConsoleCommand( "acfmenu_data3", Data.PropLength ) --For Gun ammo, Data3 should always be Propellant
+ RunConsoleCommand( "acfmenu_data4", Data.ProjLength ) --And Data4 total round mass
+ RunConsoleCommand( "acfmenu_data5", Data.FillerVol )
+ RunConsoleCommand( "acfmenu_data6", Data.WPVol )
+ RunConsoleCommand( "acfmenu_data7", Data.FuseLength )
+ RunConsoleCommand( "acfmenu_data10", Data.Tracer )
+
+ local vol = ACF.Weapons.Ammo[acfmenupanel.AmmoData["Id"]].volume
+ local Cap, CapMul, RoFMul = ACF_CalcCrateStats( vol, Data.RoundVolume )
+
+ acfmenupanel:CPanelText("BonusDisplay", "Crate info: +"..(math.Round((CapMul-1)*100,1)).."% capacity, +"..(math.Round((RoFMul-1)*-100,1)).."% RoF\nContains "..Cap.." rounds")
+
+ acfmenupanel:AmmoSlider("PropLength",Data.PropLength,Data.MinPropLength,Data.MaxTotalLength,3, "Propellant Length", "Propellant Mass : "..(math.floor(Data.PropMass*1000)).." g" ) --Propellant Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("ProjLength",Data.ProjLength,Data.MinProjLength,Data.MaxTotalLength,3, "Projectile Length", "Projectile Mass : "..(math.floor(Data.ProjMass*1000)).." g") --Projectile Length Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FillerVol",Data.FillerVol,Data.MinFillerVol,Data.MaxFillerVol,3, "Smoke Filler Volume", "Smoke Filler Mass : "..(math.floor(Data.FillerMass*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("WPVol",Data.WPVol,Data.MinFillerVol,Data.MaxFillerVol,3, "WP Filler Volume", "WP Filler Mass : "..(math.floor(Data.WPMass*1000)).." g") --HE Filler Slider (Name, Min, Max, Decimals, Title, Desc)
+ acfmenupanel:AmmoSlider("FuseLength",Data.FuseLength,0,10,1, "Fuse Time", (Data.FuseLength).." s")
+
+ acfmenupanel:AmmoCheckbox("Tracer", "Tracer : "..(math.floor(Data.Tracer*10)/10).."cm\n", "" ) --Tracer checkbox (Name, Title, Desc)
+
+ acfmenupanel:CPanelText("Desc", ACF.RoundTypes[PlayerData.Type].desc) --Description (Name, Desc)
+ acfmenupanel:CPanelText("LengthDisplay", "Round Length : "..(math.floor((Data.PropLength+Data.ProjLength+Data.Tracer)*100)/100).."/"..(Data.MaxTotalLength).." cm") --Total round length (Name, Desc)
+ acfmenupanel:CPanelText("VelocityDisplay", "Muzzle Velocity : "..math.floor(Data.MuzzleVel*ACF.VelScale).." m/s") --Proj muzzle velocity (Name, Desc)
+ ---acfmenupanel:CPanelText("BlastDisplay", "Blast Radius : "..(math.floor(Data.BlastRadius*100)/1000).." m\n") --Proj muzzle velocity (Name, Desc)
+ ---acfmenupanel:CPanelText("FragDisplay", "Fragments : "..(Data.Fragments).."\n Average Fragment Weight : "..(math.floor(Data.FragMass*10000)/10).." ---g \n Average Fragment Velocity : "..math.floor(Data.FragVel).." m/s") --Proj muzzle penetration (Name, Desc)
+
+end
+
+list.Set( "ACFRoundTypes", "SM", Round ) --Set the round properties
+list.Set( "ACFIdRounds", Round.netid, "SM" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above
diff --git a/lua/autorun/ACF_Globals.lua b/lua/autorun/ACF_Globals.lua
deleted file mode 100644
index 9aa63760a..000000000
--- a/lua/autorun/ACF_Globals.lua
+++ /dev/null
@@ -1,189 +0,0 @@
-ACF = {}
-ACF.AmmoTypes = {}
-ACF.MenuFunc = {}
-ACF.AmmoBlacklist = {}
-ACF.Version = 324 -- Make sure to change this as the version goes up or the update check is for nothing! -wrex
-ACF.CurrentVersion = 0 -- just defining a variable, do not change
-print("ACF Loaded")
-
-ACF.Threshold = 150 --Health Divisor
-ACF.PartialPenPenalty = 5 --Exponent for the damage penalty for partial penetration
-ACF.PenAreaMod = 0.85
-ACF.KinFudgeFactor = 2.1 --True kinetic would be 2, over that it's speed biaised, below it's mass biaised
-ACF.KEtoRHA = 0.25 --Empirical conversion from (kinetic energy in KJ)/(Aera in Cm2) to RHA penetration
-ACF.GroundtoRHA = 0.05 --How much mm of steel is a mm of ground worth (Real soil is about 0.15
-ACF.KEtoSpall = 1
-ACF.AmmoMod = 1 -- Ammo modifier. 1 is 1x the amount of ammo
-ACF.ArmorMod = 1
-ACF.Spalling = 0
-
-ACF.HEPower = 6000 --HE Filler power per KG in KJ
-ACF.HEDensity = 1.65 --HE Filler density (That's TNT density)
-ACF.HEFrag = 1500 --Mean fragment number for equal weight TNT and casing
-ACF.HEBlastPen = 0.4 --Blast penetration exponent based of HE power
-
-ACF.HEATMVScale = 0.73 --Filler KE to HEAT slug KE conversion expotential
-
-ACF.DragDiv = 40 --Drag fudge factor
-ACF.VelScale = 1 --Scale factor for the shell velocities in the game world
--- local PhysEnv = physenv.GetPerformanceSettings()
-ACF.PhysMaxVel = 4000
-
-ACF.PBase = 1050 --1KG of propellant produces this much KE at the muzzle, in kj
-ACF.PScale = 1 --Gun Propellant power expotential
-ACF.MVScale = 0.5 --Propellant to MV convertion expotential
-ACF.PDensity = 1.6 --Gun propellant density (Real powders go from 0.7 to 1.6, i'm using higher densities to simulate case bottlenecking)
-
-ACF.Year = 1945
-
-CreateConVar('sbox_max_acf_gun', 12)
-CreateConVar('sbox_max_acf_ammo', 32)
-CreateConVar('sbox_max_acf_misc', 32)
-
-AddCSLuaFile( "acf_globals.lua" )
-AddCSLuaFile( "acf/client/cl_acfballistics.lua" )
-AddCSLuaFile( "acf/client/cl_acfmenu_gui.lua" )
-
-AddCSLuaFile( "acf/client/cl_acfballistics.lua" )
-AddCSLuaFile( "acf/client/cl_acfmenu_gui.lua" )
-
-if (SERVER) then
-
- include("acf/server/sv_acfbase.lua")
- include("acf/server/sv_acfdamage.lua")
- include("acf/server/sv_acfballistics.lua")
-
-elseif (CLIENT) then
-
- include("acf/client/cl_acfballistics.lua")
- --include("ACF/Client/cl_ACFMenu_GUI.lua")
-
-end
-
-include("acf/shared/rounds/roundap.lua")
-include("acf/shared/rounds/roundaphe.lua")
-include("acf/shared/rounds/roundhe.lua")
-include("acf/shared/rounds/roundheat.lua")
-include("acf/shared/rounds/roundhp.lua")
-include("acf/shared/rounds/roundsmoke.lua")
-include("acf/shared/rounds/roundrefill.lua")
-include("acf/shared/rounds/roundfunctions.lua")
-
-include("acf/shared/acfgunlist.lua")
-include("acf/shared/acfmobilitylist.lua")
-include("acf/shared/acfsensorlist.lua")
-include("acf/shared/acfmissilelist.lua")
-
-ACF.Weapons = list.Get("ACFEnts")
-
-ACF.Classes = list.Get("ACFClasses")
-
-ACF.RoundTypes = list.Get("ACFRoundTypes")
-
-ACF.IdRounds = list.Get("ACFIdRounds") --Lookup tables so i can get rounds classes from clientside with just an integer
-
-timer.Simple(5,function()
- game.AddParticles("particles/acf_muzzleflashes.pcf")
- game.AddParticles("particles/explosion1.pcf")
- game.AddParticles("particles/rocket_motor.pcf")
-
-
- for Class,Table in pairs(ACF.Classes["GunClass"]) do
- PrecacheParticleSystem(Table["muzzleflash"])
- end
-end)
-
-function ACF_MuzzleVelocity( Propellant, Mass, Caliber )
-
- local PEnergy = ACF.PBase * ((1+Propellant)^ACF.PScale-1)
- local Speed = ((PEnergy*2000/Mass)^ACF.MVScale)
- local Final = Speed -- - Speed * math.Clamp(Speed/2000,0,0.5)
-
- return Final
-end
-
-function ACF_Kinetic( Speed , Mass, LimitVel )
-
- LimitVel = LimitVel or 99999
- Speed = Speed/39.37
-
- local Energy = {}
- Energy.Kinetic = ((Mass) * ((Speed)^2))/2000 --Energy in KiloJoules
- Energy.Momentum = (Speed * Mass)
-
- local KE = (Mass * (Speed^ACF.KinFudgeFactor))/2000 + Energy.Momentum
- Energy.Penetration = math.max( KE - (math.max(Speed-LimitVel,0)^2)/(LimitVel*5) * (KE/200)^0.95 , KE*0.1 )
- --Energy.Penetration = math.max( KE - (math.max(Speed-LimitVel,0)^2)/(LimitVel*5) * (KE/200)^0.95 , KE*0.1 )
- --Energy.Penetration = math.max(Energy.Momentum^ACF.KinFudgeFactor - math.max(Speed-LimitVel,0)/(LimitVel*5) * Energy.Momentum , Energy.Momentum*0.1)
-
- return Energy
-end
-
--- New healthmod/armormod/ammomod cvars
-CreateConVar("acf_healthmod", 1)
-CreateConVar("acf_armormod", 1)
-CreateConVar("acf_ammomod", 1)
-CreateConVar("acf_spalling", 0)
-
-function ACF_CVarChangeCallback(CVar, Prev, New)
- if( CVar == "acf_healthmod" ) then
- ACF.Threshold = 150 / math.max(New, 0.01)
- print ("Health Mod changed to a factor of " .. New)
- elseif( CVar == "acf_armormod" ) then
- ACF.ArmorMod = 1 * math.max(New, 0)
- print ("Armor Mod changed to a factor of " .. New)
- elseif( CVar == "acf_ammomod" ) then
- ACF.AmmoMod = 1 * math.max(New, 0.01)
- print ("Ammo Mod changed to a factor of " .. New)
- elseif( CVar == "acf_spalling" ) then
- ACF.Spalling = math.floor(math.Clamp(New, 0, 1))
- local text = "off"
- if(ACF.Spalling > 0) then
- text = "on"
- end
- print ("ACF Spalling is now " .. text)
- end
-end
-
-
-function ACF_UpdateChecking( )
-
- print("Checking for updates....")
-
- http.Fetch("http://acf.googlecode.com/svn/",function(contents,size)
- local rev = tonumber(string.match( contents, "Revision ([0-9]+)" ))
- if rev and ACF.Version >= rev then
- print("ACF Is Up To Date, Latest Version: "..rev)
-
- elseif !rev then
- print("No Internet Connection Detected! ACF Update Check Failed")
- else
- print("A newer version of ACF is available! Version: "..rev..", You have Version: "..ACF.Version)
-
- print("Please update!")
- end
- ACF.CurrentVersion = rev
-
- end, function() end)
-end
-ACF_UpdateChecking( )
-
-
-
-function ACF_ChatVersionPrint(ply)
- if ACF.Version < ACF.CurrentVersion then
- timer.Simple( 2,function()
- ply:SendLua(
- "chat.AddText(Color(255,0,0),\"A newer version of ACF is available! Version: \"..ACF.CurrentVersion)"
- )
- end)
- end
-end
-
-hook.Add("PlayerInitialSpawn","versioncheck",ACF_ChatVersionPrint)
-
-
-cvars.AddChangeCallback("acf_healthmod", ACF_CVarChangeCallback)
-cvars.AddChangeCallback("acf_armormod", ACF_CVarChangeCallback)
-cvars.AddChangeCallback("acf_ammomod", ACF_CVarChangeCallback)
-cvars.AddChangeCallback("acf_spalling", ACF_CVarChangeCallback)
\ No newline at end of file
diff --git a/lua/autorun/aaa_autoincludes.lua b/lua/autorun/aaa_autoincludes.lua
new file mode 100644
index 000000000..f76909d76
--- /dev/null
+++ b/lua/autorun/aaa_autoincludes.lua
@@ -0,0 +1,53 @@
+AddCSLuaFile("autorun/aaa_autoincludes.lua")
+
+aaa_debug = false
+
+function aaa_IncludeHere(dir)
+ //print("hi from "..dir)
+ local files, folders = file.Find(dir.."/*", "LUA")
+
+ for k,v in pairs(file.Find(dir.."/*.lua", "LUA")) do
+ if aaa_debug then Msg("AAA: including file \""..dir.."/"..v.."\"!\n") end
+ include(dir.."/"..v)
+ end
+
+ for _, fdir in pairs(folders) do
+ aaa_IncludeHere(dir.."/"..fdir)
+ end
+
+end
+
+
+
+function aaa_IncludeClient(dir)
+
+ local files, folders = file.Find(dir.."/*", "LUA")
+
+ for k,v in pairs(file.Find(dir.."/*.lua", "LUA")) do
+ if aaa_debug then Msg("AAA: adding client file \""..dir.."/"..v.."\"!\n") end
+ AddCSLuaFile(dir.."/"..v)
+ end
+
+ for _, fdir in pairs(folders) do
+ aaa_IncludeClient(dir.."/"..fdir)
+ end
+
+end
+
+
+
+function aaa_IncludeShared(dir)
+
+ local files, folders = file.Find(dir.."/*", "LUA")
+
+ for k,v in pairs(file.Find(dir.."/*.lua", "LUA")) do
+ if aaa_debug then Msg("AAA: adding client file \""..dir.."/"..v.."\"!\n") end
+ include(dir.."/"..v)
+ AddCSLuaFile(dir.."/"..v)
+ end
+
+ for _, fdir in pairs(folders) do
+ aaa_IncludeShared(dir.."/"..fdir)
+ end
+
+end
diff --git a/lua/autorun/acf_globals.lua b/lua/autorun/acf_globals.lua
new file mode 100644
index 000000000..06514ef54
--- /dev/null
+++ b/lua/autorun/acf_globals.lua
@@ -0,0 +1,615 @@
+ACF = {}
+ACF.AmmoTypes = {}
+ACF.MenuFunc = {}
+ACF.AmmoBlacklist = {}
+ACF.Version = 663 -- REMEMBER TO CHANGE THIS FOR GODS SAKE, OMFG!!!!!!! -wrex Update the changelog too! -Ferv
+ACF.CurrentVersion = 0 -- just defining a variable, do not change
+
+ACF.Year = 1945
+
+ACF.Threshold = 264.7 --Health Divisor (don't forget to update cvar function down below)
+ACF.PartialPenPenalty = 5 --Exponent for the damage penalty for partial penetration
+ACF.PenAreaMod = 0.85
+ACF.KinFudgeFactor = 2.1 --True kinetic would be 2, over that it's speed biaised, below it's mass biaised
+ACF.KEtoRHA = 0.25 --Empirical conversion from (kinetic energy in KJ)/(Aera in Cm2) to RHA penetration
+ACF.GroundtoRHA = 0.15 --How much mm of steel is a mm of ground worth (Real soil is about 0.15)
+ACF.KEtoSpall = 1
+ACF.AmmoMod = 1.05 -- Ammo modifier. 1 is 1x the amount of ammo. 0.6 default
+ACF.CrateVolEff = 0.1576 -- magic number that adjusts the efficiency of crate model volume to ammo capacity
+ACF.ArmorMod = 1
+ACF.SlopeEffectFactor = 1.1 -- Sloped armor effectiveness: armor / cos(angle)^factor
+ACF.Spalling = 0
+ACF.GunfireEnabled = true
+ACF.MeshCalcEnabled = false
+
+ACF.HEPower = 8000 --HE Filler power per KG in KJ
+ACF.HEDensity = 1.65 --HE Filler density (That's TNT density)
+ACF.HEFrag = 1500 --Mean fragment number for equal weight TNT and casing
+ACF.HEBlastPen = 0.4 --Blast penetration exponent based of HE power
+ACF.HEFeatherExp = 0.5 --exponent applied to HE dist/maxdist feathering, <1 will increasingly bias toward max damage until sharp falloff at outer edge of range
+
+ACF.HEATMVScale = 0.75 --Filler KE to HEAT slug KE conversion expotential
+ACF.HEATMulAmmo = 30 --HEAT slug damage multiplier; 13.2x roughly equal to AP damage
+ACF.HEATMulFuel = 4 --needs less multiplier, much less health than ammo
+ACF.HEATMulEngine = 10 --likewise
+ACF.HEATPenLayerMul = 0.75 --HEAT base energy multiplier
+ACF.HEATBoomConvert = 1/3 -- percentage of filler that creates HE damage at detonation
+ACF.HEATMinCrush = 800 -- vel where crush starts, progressively converting round to raw HE
+ACF.HEATMaxCrush = 1200 -- vel where fully crushed
+
+ACF.DragDiv = 40 --Drag fudge factor
+ACF.VelScale = 1 --Scale factor for the shell velocities in the game world
+-- local PhysEnv = physenv.GetPerformanceSettings()
+ACF.PhysMaxVel = 4000
+ACF.SmokeWind = 5 + math.random()*35 --affects the ability of smoke to be used for screening effect
+
+ACF.PBase = 1050 --1KG of propellant produces this much KE at the muzzle, in kj
+ACF.PScale = 1 --Gun Propellant power expotential
+ACF.MVScale = 0.5 --Propellant to MV convertion expotential
+ACF.PDensity = 1.6 --Gun propellant density (Real powders go from 0.7 to 1.6, i'm using higher densities to simulate case bottlenecking)
+
+ACF.TorqueBoost = 1.25 --torque multiplier from using fuel
+ACF.FuelRate = 5 --multiplier for fuel usage, 1.0 is approx real world
+ACF.ElecRate = 1.5 --multiplier for electrics
+ACF.TankVolumeMul = 0.5 -- multiplier for fuel tank capacity, 1.0 is approx real world
+
+--[[
+ random, low cost legality check that discourages attempts to game checking with a hard to predict timing and punishing lockout time
+ usage:
+ Ent.Legal, Ent.LegalIssues = ACF_CheckLegal(Ent, Model, MinMass, MinInertia, CanMakesphere, Parentable, ParentRequiresWeld, CanVisclip)
+ Ent.NextLegalCheck = ACF.LegalSettings:NextCheck(Ent.Legal)
+]]
+ACF.LegalSettings = {
+ CanModelSwap = false,
+ Min = 5, -- min seconds between checks
+ Max = 25, -- max seconds between checks
+ Lockout = 35, -- lockout time on not legal
+ NextCheck = function(self, Legal) return ACF.CurTime + (Legal and math.random(self.Min, self.Max) or self.Lockout) end
+}
+
+ACF.FuelDensity = { --kg/liter
+ Diesel = 0.832,
+ Petrol = 0.745,
+ Electric = 3.89 -- li-ion
+}
+
+ACF.Efficiency = { --how efficient various engine types are, higher is worse
+ GenericPetrol = 0.304, --kg per kw hr
+ GenericDiesel = 0.243, --up to 0.274
+ Turbine = 0.375, -- previously 0.231
+ Wankel = 0.335,
+ Radial = 0.4, -- 0.38 to 0.53
+ Electric = 0.85 --percent efficiency converting chemical kw into mechanical kw
+}
+
+ACF.TorqueScale = { --how fast damage drops torque, lower loses more % torque
+ GenericPetrol = 0.25,
+ GenericDiesel = 0.35,
+ Turbine = 0.2,
+ Wankel = 0.2,
+ Radial = 0.3,
+ Electric = 0.5
+}
+
+ACF.EngineHPMult = { --health multiplier for engines
+ GenericPetrol = 0.2,
+ GenericDiesel = 0.5,
+ Turbine = 0.125,
+ Wankel = 0.125,
+ Radial = 0.3,
+ Electric = 0.75
+}
+
+ACF.LiIonED = 0.458 -- li-ion energy density: kw hours / liter
+ACF.CuIToLiter = 0.0163871 -- cubic inches to liters
+
+ACF.RefillDistance = 300 --Distance in which ammo crate starts refilling.
+ACF.RefillSpeed = 700 -- (ACF.RefillSpeed / RoundMass) / Distance
+
+ACF.ChildDebris = 50 -- higher is more debris props; Chance = ACF.ChildDebris / num_children; Only applies to children of acf-killed parent props
+ACF.DebrisIgniteChance = 0.25
+ACF.DebrisScale = 20 -- Ignore debris that is less than this bounding radius.
+ACF.SpreadScale = 4 -- The maximum amount that damage can decrease a gun's accuracy. Default 4x
+ACF.GunInaccuracyScale = 1 -- A multiplier for gun accuracy.
+ACF.GunInaccuracyBias = 2 -- Higher numbers make shots more likely to be inaccurate. Choose between 0.5 to 4. Default is 2 (unbiased).
+
+ACF.EnableDefaultDP = false -- Enable the inbuilt damage protection system.
+
+ACF.EnableKillicons = true -- Enable killicons overwriting.
+
+if file.Exists("acf/shared/acf_userconfig.lua", "LUA") then
+ include("acf/shared/acf_userconfig.lua")
+end
+
+
+CreateConVar('sbox_max_acf_gun', 16)
+CreateConVar('sbox_max_acf_smokelauncher', 10)
+CreateConVar('sbox_max_acf_ammo', 32)
+CreateConVar('sbox_max_acf_misc', 32)
+CreateConVar('acf_meshvalue', 1)
+CreateConVar("sbox_acf_restrictinfo", 1) -- 0=any, 1=owned
+
+AddCSLuaFile()
+AddCSLuaFile( "acf/client/cl_acfballistics.lua" )
+AddCSLuaFile( "acf/client/cl_acfmenu_gui.lua" )
+AddCSLuaFile( "acf/client/cl_acfrender.lua" )
+
+if SERVER and ACF.EnableDefaultDP then
+ AddCSLuaFile( "acf/client/cl_acfpermission.lua" )
+ AddCSLuaFile( "acf/client/gui/cl_acfsetpermission.lua" )
+end
+
+if SERVER then
+
+ util.AddNetworkString( "ACF_KilledByACF" )
+ util.AddNetworkString( "ACF_RenderDamage" )
+ util.AddNetworkString( "ACF_Notify" )
+
+ include("acf/server/sv_acfbase.lua")
+ include("acf/server/sv_acfdamage.lua")
+ include("acf/server/sv_acfballistics.lua")
+
+ if ACF.EnableDefaultDP then
+ include("acf/server/sv_acfpermission.lua")
+ end
+
+elseif CLIENT then
+
+ include("acf/client/cl_acfballistics.lua")
+ include("acf/client/cl_acfrender.lua")
+
+ if ACF.EnableDefaultDP then
+ include("acf/client/cl_acfpermission.lua")
+ include("acf/client/gui/cl_acfsetpermission.lua")
+ end
+
+ CreateConVar("acf_cl_particlemul", 1)
+ CreateClientConVar("ACF_MobilityRopeLinks", "1", true, true)
+
+ -- Cache results so we don't need to do expensive filesystem checks every time
+ local IsValidCache = {}
+
+ -- Returns whether or not a sound actually exists, fixes client timeout issues
+ function IsValidSound( path )
+ if IsValidCache[path] == nil then
+ IsValidCache[path] = file.Exists( string.format( "sound/%s", tostring( path ) ), "GAME" ) and true or false
+ end
+ return IsValidCache[path]
+ end
+
+end
+
+include("acf/shared/rounds/roundap.lua")
+include("acf/shared/rounds/roundaphe.lua")
+include("acf/shared/rounds/roundhe.lua")
+include("acf/shared/rounds/roundheat.lua")
+include("acf/shared/rounds/roundheatfs.lua")
+include("acf/shared/rounds/roundapfsds.lua")
+include("acf/shared/rounds/roundapds.lua")
+include("acf/shared/rounds/roundapcr.lua")
+include("acf/shared/rounds/roundfl.lua")
+include("acf/shared/rounds/roundhp.lua")
+include("acf/shared/rounds/roundsmoke.lua")
+include("acf/shared/rounds/roundrefill.lua")
+include("acf/shared/rounds/roundfunctions.lua")
+
+include("acf/shared/acfloader.lua")
+include("acf/shared/acfcratelist.lua")
+--include("acf/shared/acfmissilelist.lua")
+
+ACF.Weapons = list.Get("ACFEnts")
+
+ACF.Classes = list.Get("ACFClasses")
+
+ACF.RoundTypes = list.Get("ACFRoundTypes")
+
+ACF.IdRounds = list.Get("ACFIdRounds") --Lookup tables so i can get rounds classes from clientside with just an integer
+
+game.AddParticles("particles/acf_muzzleflashes.pcf")
+game.AddParticles("particles/explosion1.pcf")
+game.AddParticles("particles/rocket_motor.pcf")
+
+game.AddDecal("GunShot1", "decals/METAL/shot5")
+
+-- Add the ACF tool category
+if CLIENT then
+
+ ACF.CustomToolCategory = CreateClientConVar( "acf_tool_category", 0, true, false );
+
+ if( ACF.CustomToolCategory:GetBool() ) then
+
+ language.Add( "spawnmenu.tools.acf", "ACF" );
+
+ -- We use this hook so that the ACF category is always at the top
+ hook.Add( "AddToolMenuTabs", "CreateACFCategory", function()
+
+ spawnmenu.AddToolCategory( "Main", "ACF", "#spawnmenu.tools.acf" );
+
+ end );
+
+ end
+
+end
+
+timer.Simple( 0, function()
+ for Class,Table in pairs(ACF.Classes["GunClass"]) do
+ PrecacheParticleSystem(Table["muzzleflash"])
+ end
+end)
+
+--Stupid workaround red added to precache timescaling.
+hook.Add( "Think", "Update ACF Internal Clock", function()
+ ACF.CurTime = CurTime()
+ ACF.SysTime = SysTime()
+end )
+
+-- changes here will be automatically reflected in the armor properties tool
+function ACF_CalcArmor( Area, Ductility, Mass )
+
+ return ( Mass * 1000 / Area / 0.78 ) / ( 1 + Ductility ) ^ 0.5 * ACF.ArmorMod
+
+end
+
+function ACF_MuzzleVelocity( Propellant, Mass, Caliber )
+
+ local PEnergy = ACF.PBase * ((1+Propellant)^ACF.PScale-1)
+ local Speed = ((PEnergy*2000/Mass)^ACF.MVScale)
+ local Final = Speed -- - Speed * math.Clamp(Speed/2000,0,0.5)
+
+ return Final
+end
+
+function ACF_Kinetic( Speed , Mass, LimitVel )
+
+ LimitVel = LimitVel or 99999
+ Speed = Speed/39.37
+
+ local Energy = {}
+ Energy.Kinetic = ((Mass) * ((Speed)^2))/2000 --Energy in KiloJoules
+ Energy.Momentum = (Speed * Mass)
+
+ local KE = (Mass * (Speed^ACF.KinFudgeFactor))/2000 + Energy.Momentum
+ Energy.Penetration = math.max( KE - (math.max(Speed-LimitVel,0)^2)/(LimitVel*5) * (KE/200)^0.95 , KE*0.1 )
+ --Energy.Penetration = math.max( KE - (math.max(Speed-LimitVel,0)^2)/(LimitVel*5) * (KE/200)^0.95 , KE*0.1 )
+ --Energy.Penetration = math.max(Energy.Momentum^ACF.KinFudgeFactor - math.max(Speed-LimitVel,0)/(LimitVel*5) * Energy.Momentum , Energy.Momentum*0.1)
+
+ return Energy
+end
+
+-- returns last parent in chain, which has physics
+function ACF_GetPhysicalParent( obj )
+ if not IsValid(obj) then return nil end
+
+ --check for fresh cached parent
+ if obj.acfphysparent and ACF.CurTime < obj.acfphysstale then
+ return obj.acfphysparent
+ end
+
+ local Parent = obj
+
+ while Parent:GetParent():IsValid() do
+ Parent = Parent:GetParent()
+ end
+
+ --update cached parent
+ obj.acfphysparent = Parent
+ obj.acfphysstale = ACF.CurTime + 10 --when cached parent is considered stale and needs updating
+
+ return Parent
+end
+
+-- returns any wheels linked to this or child gearboxes
+function ACF_GetLinkedWheels( MobilityEnt )
+ if not IsValid( MobilityEnt ) then return {} end
+
+ local ToCheck = {}
+ local Wheels = {}
+
+ local links = MobilityEnt.GearLink or MobilityEnt.WheelLink -- handling for usage on engine or gearbox
+ for k,link in pairs( links ) do table.insert(ToCheck, link.Ent) end
+
+ -- use a stack to traverse the link tree looking for wheels at the end
+ while #ToCheck > 0 do
+ local Ent = table.remove(ToCheck,#ToCheck)
+ if IsValid(Ent) then
+ if Ent:GetClass() == "acf_gearbox" then
+ for k,v in pairs( Ent.WheelLink ) do
+ table.insert(ToCheck, v.Ent)
+ end
+ else
+ Wheels[Ent] = Ent -- indexing it same as ACF_GetAllPhysicalConstraints, for easy merge. whoever indexed by entity in that function, uuuuuuggghhhhh
+ end
+ end
+ end
+
+ return Wheels
+end
+
+-- Global Ratio Setting Function
+function ACF_CalcMassRatio( obj, pwr )
+ if not IsValid(obj) then return end
+ local Mass = 0
+ local PhysMass = 0
+ local power = 0
+ local fuel = 0
+
+ -- find the physical parent highest up the chain
+ local Parent = ACF_GetPhysicalParent(obj)
+
+ -- get the shit that is physically attached to the vehicle
+ local PhysEnts = ACF_GetAllPhysicalConstraints( Parent )
+
+ -- add any parented but not constrained props you sneaky bastards
+ local AllEnts = table.Copy( PhysEnts )
+ for k, v in pairs( AllEnts ) do
+
+ table.Merge( AllEnts, ACF_GetAllChildren( v ) )
+
+ end
+
+ for k, v in pairs( AllEnts ) do
+
+ if IsValid( v ) then
+
+ if v:GetClass() == "acf_engine" then
+ power = power + (v.peakkw * 1.34)
+ fuel = v.RequiresFuel and 2 or fuel
+ elseif v:GetClass() == "acf_fueltank" then
+ fuel = math.max(fuel,1)
+ end
+
+ local phys = v:GetPhysicsObject()
+ if IsValid( phys ) then
+
+ Mass = Mass + phys:GetMass()
+
+ if PhysEnts[ v ] then
+ PhysMass = PhysMass + phys:GetMass()
+ end
+
+ end
+
+ end
+
+ end
+
+ -- todo: replace with a reference to table containing data
+ for k, v in pairs( AllEnts ) do
+ v.acfphystotal = PhysMass
+ v.acftotal = Mass
+ v.acflastupdatemass = ACF.CurTime
+ end
+
+ if pwr then return { Power = power, Fuel = fuel } end
+end
+
+-- checks if an ent meets the given requirements for legality
+-- MinInertia needs to be mass normalized (normalized=inertia/mass)
+-- ballistics doesn't check visclips on anything except prop_physics, so no need to check on acf ents
+function ACF_CheckLegal(Ent, Model, MinMass, MinInertia, CanMakesphere, Parentable, ParentRequiresWeld, CanVisclip)
+ -- check it exists
+ if not IsValid(Ent) then return {Legal=false, Problems={"Invalid Ent"}} end
+
+ local problems = {}
+ local physobj = Ent:GetPhysicsObject()
+
+ -- check if physics is valid
+ if not IsValid(physobj) then return {Legal=false, Problems={"Invalid Physics"}} end
+
+ --make sure traces can hit it (fade door, propnotsolid)
+ if not Ent:IsSolid() then
+ table.insert(problems,"Not solid")
+ end
+
+ -- check if the model matches
+ if Model != nil and not ACF.LegalSettings.CanModelSwap then
+ if Ent:GetModel() != Model then
+ table.insert(problems,"Wrong model")
+ end
+ end
+
+ -- check mass
+ if MinMass != nil and (physobj:GetMass() < MinMass) then
+ table.insert(problems,"Under min mass")
+ end
+
+ -- check inertia components
+ if MinInertia != nil then
+ local inertia = physobj:GetInertia()/physobj:GetMass()
+ if (inertia.x < MinInertia.x) or (inertia.y < MinInertia.y) or (inertia.z < MinInertia.z) then
+ table.insert(problems,"Under min inertia")
+ end
+ end
+
+ -- check makesphere
+ if not CanMakesphere and (physobj:GetVolume() == nil) then
+ table.insert(problems,"Makesphere")
+ end
+
+ -- check for clips
+ if not CanVisclip and (Ent.ClipData != nil) and (#Ent.ClipData > 0) then
+ table.insert(problems,"Visclip")
+ end
+
+ -- if it has a parent, check if legally parented
+ if IsValid( Ent:GetParent() ) then
+
+ -- if no parenting allowed
+ if not (Parentable or ParentRequiresWeld) then
+ table.insert(problems,"Parented")
+ end
+
+ -- legal if weld not required, otherwise check if parented with weld
+ if ParentRequiresWeld then
+ local welded = false
+ local rootparent = ACF_GetPhysicalParent(Ent)
+
+ --make sure it's welded to root parent
+ for k, v in pairs( constraint.FindConstraints( Ent, "Weld" ) ) do
+ if v.Ent1 == rootparent or v.Ent2 == rootparent then
+ welded = true
+ break
+ end
+ end
+
+ if not welded then
+ table.insert(problems,"Parented without weld to root parent")
+ end
+ end
+ end
+
+ -- legal if number of problems is 0
+ return (#problems == 0), table.concat(problems, ", ")
+end
+
+-- Cvars for recoil/he push
+CreateConVar("acf_hepush", 1)
+CreateConVar("acf_recoilpush", 1)
+
+-- New healthmod/armormod/ammomod cvars
+CreateConVar("acf_healthmod", 1)
+CreateConVar("acf_armormod", 1)
+CreateConVar("acf_ammomod", 1)
+CreateConVar("acf_spalling", 0)
+CreateConVar("acf_gunfire", 1)
+CreateConVar("acf_modelswap_legal", 0)
+
+function ACF_CVarChangeCallback(CVar, Prev, New)
+ if( CVar == "acf_healthmod" ) then
+ ACF.Threshold = 264.7 / math.max(New, 0.01)
+ print ("Health Mod changed to a factor of " .. New)
+ elseif( CVar == "acf_armormod" ) then
+ ACF.ArmorMod = 1 * math.max(New, 0)
+ print ("Armor Mod changed to a factor of " .. New)
+ elseif( CVar == "acf_ammomod" ) then
+ ACF.AmmoMod = 1 * math.max(New, 0.01)
+ print ("Ammo Mod changed to a factor of " .. New)
+ elseif( CVar == "acf_spalling" ) then
+ ACF.Spalling = math.floor(math.Clamp(New, 0, 1))
+ local text = "off"
+ if(ACF.Spalling > 0) then
+ text = "on"
+ end
+ print ("ACF Spalling is now " .. text)
+ elseif( CVar == "acf_gunfire" ) then
+ ACF.GunfireEnabled = tobool( New )
+ local text = "disabled"
+ if ACF.GunfireEnabled then
+ text = "enabled"
+ end
+ print ("ACF Gunfire has been " .. text)
+ elseif CVar == "acf_modelswap_legal" then
+ ACF.LegalSettings.CanModelSwap = tobool( New )
+ print("ACF model swapping is set to " .. (ACF.LegalSettings.CanModelSwap and "legal" or "not legal"))
+ end
+end
+
+if SERVER then
+ function ACF_SendNotify( ply, success, msg )
+ net.Start( "ACF_Notify" )
+ net.WriteBit( success )
+ net.WriteString( msg or "" )
+ net.Send( ply )
+ end
+else
+ local function ACF_Notify()
+ local Type = NOTIFY_ERROR
+ if tobool( net.ReadBit() ) then Type = NOTIFY_GENERIC end
+
+ GAMEMODE:AddNotify( net.ReadString(), Type, 7 )
+ end
+ net.Receive( "ACF_Notify", ACF_Notify )
+end
+
+function ACF_UpdateChecking( )
+ http.Fetch("https://github.com/nrlulz/ACF",function(contents,size)
+ local rev = tonumber(string.match( contents, "%s*(%d+)\n%s*\n%s*commits" )) or 0 --"history\">\n%s*(%d+)\n%s*"
+ if rev and ACF.Version >= rev then
+ print("[ACF] ACF Is Up To Date, Latest Version: "..rev)
+ elseif !rev then
+ print("[ACF] No Internet Connection Detected! ACF Update Check Failed")
+ else
+ print("[ACF] A newer version of ACF is available! Version: "..rev..", You have Version: "..ACF.Version)
+ if CLIENT then chat.AddText( Color( 255, 0, 0 ), "A newer version of ACF is available!" ) end
+ end
+ ACF.CurrentVersion = rev
+
+ end, function() end)
+end
+ACF_UpdateChecking( )
+
+local function OnInitialSpawn( ply )
+ local Table = {}
+ for k,v in pairs( ents.GetAll() ) do
+ if v.ACF and v.ACF.PrHealth then
+ table.insert(Table,{ID = v:EntIndex(), Health = v.ACF.Health, v.ACF.MaxHealth})
+ end
+ end
+ if Table ~= {} then
+ net.Start("ACF_RenderDamage")
+ net.WriteTable(Table)
+ net.Send(ply)
+ end
+end
+
+hook.Add( "PlayerInitialSpawn", "renderdamage", OnInitialSpawn )
+
+cvars.AddChangeCallback("acf_healthmod", ACF_CVarChangeCallback)
+cvars.AddChangeCallback("acf_armormod", ACF_CVarChangeCallback)
+cvars.AddChangeCallback("acf_ammomod", ACF_CVarChangeCallback)
+cvars.AddChangeCallback("acf_spalling", ACF_CVarChangeCallback)
+cvars.AddChangeCallback("acf_gunfire", ACF_CVarChangeCallback)
+
+-- smoke-wind cvar handling
+if SERVER then
+ local function msgtoconsole(hud, msg)
+ print(msg)
+ end
+
+ util.AddNetworkString("acf_smokewind")
+ concommand.Add( "acf_smokewind", function(ply, cmd, args, str)
+ local validply = IsValid(ply)
+ local printmsg = validply and function(hud, msg) ply:PrintMessage(hud, msg) end or msgtoconsole
+
+ if not args[1] then printmsg(HUD_PRINTCONSOLE,
+ "Set the wind intensity upon all smoke munitions." ..
+ "\n This affects the ability of smoke to be used for screening effect." ..
+ "\n Example; acf_smokewind 300")
+ return false
+ end
+
+ if validply and not ply:IsAdmin() then
+ printmsg(HUD_PRINTCONSOLE, "You can't use this because you are not an admin.")
+ return false
+
+ else
+ local wind = tonumber(args[1])
+
+ if not wind then
+ printmsg(HUD_PRINTCONSOLE, "Command unsuccessful: that wind value could not be interpreted as a number!")
+ return false
+ end
+
+ ACF.SmokeWind = wind
+
+ net.Start("acf_smokewind")
+ net.WriteFloat(wind)
+ net.Broadcast()
+
+ printmsg(HUD_PRINTCONSOLE, "Command SUCCESSFUL: set smoke-wind to " .. wind .. "!")
+ return true
+ end
+ end)
+
+ local function sendSmokeWind(ply)
+ net.Start("acf_smokewind")
+ net.WriteFloat(ACF.SmokeWind)
+ net.Send(ply)
+ end
+ hook.Add( "PlayerInitialSpawn", "ACF_SendSmokeWind", sendSmokeWind )
+else
+ local function recvSmokeWind(len)
+ ACF.SmokeWind = net.ReadFloat()
+ end
+ net.Receive("acf_smokewind", recvSmokeWind)
+end
\ No newline at end of file
diff --git a/lua/autorun/battlepod.lua b/lua/autorun/battlepod.lua
index 2a9bf3f9d..7d64fd44e 100644
--- a/lua/autorun/battlepod.lua
+++ b/lua/autorun/battlepod.lua
@@ -1,9 +1,5 @@
-local function HandleACFSeatAnimation( vehicle, player )
- return player:SelectWeightedSequence( ACT_GMOD_SIT_ROLLERCOASTER )
-end
-
local function HandleACFPodAnimation( vehicle, player )
- return player:SelectWeightedSequence( ACT_GMOD_SIT_ROLLERCOASTER )
+ return player:LookupSequence("drive_pd")
end
local Category = "Armoured Combat Framework"
@@ -40,8 +36,5 @@ local V = {
vehiclescript = "scripts/vehicles/prisoner_pod.txt",
limitview = "0"
},
- Members = {
- HandleAnimation = HandleACFSeatAnimation
- }
}
list.Set( "Vehicles", "acf_pilotseat", V )
diff --git a/lua/autorun/killicons.lua b/lua/autorun/killicons.lua
new file mode 100644
index 000000000..c42c5a5dd
--- /dev/null
+++ b/lua/autorun/killicons.lua
@@ -0,0 +1,267 @@
+--[[----------------------------------------------------------------------------
+
+ Even bigger hack to get killicons
+
+ Basically copied and modified default (base gamemode) functions.
+
+ Functions which process next string:
+ "PlayerKilledByPlayer";
+ "PlayerKilled";
+ "PlayerKilledNPC";
+ "NPCKilledNPC"
+ are copied from 'cl_deathnotice.lua' to this file and
+ 'attached' to next network strings accordingly:
+ "ACF_PlayerKilledByPlayer";
+ "ACF_PlayerKilled";
+ "ACF_PlayerKilledNPC";
+ "ACF_NPCKilledNPC"
+
+ Data sent through these network strings is generated by functions
+ ACF_OnNPCKilled and ACF_PlayerDeath which are hooked to functions
+ OnNPCKilled and PlayerDeath and are their modified copies.
+
+ They are modified to check if inflictor entity has 'ACF' table
+ attached and if so to send its ACF class.
+
+------------------------------------------------------------------------------]]
+AddCSLuaFile()
+
+if SERVER then
+ if ACF.EnableKillicons then
+ util.AddNetworkString( "ACF_PlayerKilledNPC" )
+ util.AddNetworkString( "ACF_NPCKilledNPC" )
+
+ local function ACF_OnNPCKilled( ent, attacker, inflictor )
+ -- Don't spam the killfeed with scripted stuff
+ if ( ent:GetClass() == "npc_bullseye" || ent:GetClass() == "npc_launcher" ) then return end
+
+ if ( IsValid( attacker ) && attacker:GetClass() == "trigger_hurt" ) then attacker = ent end
+
+ if ( IsValid( attacker ) && attacker:IsVehicle() && IsValid( attacker:GetDriver() ) ) then
+ attacker = attacker:GetDriver()
+ end
+
+ if ( !IsValid( inflictor ) && IsValid( attacker ) ) then
+ inflictor = attacker
+ end
+
+ -- Convert the inflictor to the weapon that they're holding if we can.
+ if ( IsValid( inflictor ) && attacker == inflictor && ( inflictor:IsPlayer() || inflictor:IsNPC() ) ) then
+
+ inflictor = inflictor:GetActiveWeapon()
+ if ( !IsValid( attacker ) ) then inflictor = attacker end
+
+ end
+
+ local InflictorClass = "worldspawn"
+ local AttackerClass = "worldspawn"
+
+ if ( IsValid( inflictor ) ) then
+ if inflictor.ACF and inflictor:GetClass() != "acf_ammo" then
+ InflictorClass = "acf_" .. inflictor.Class
+ else
+ InflictorClass = inflictor:GetClass()
+ end
+ end
+
+ if ( IsValid( attacker ) ) then
+
+ AttackerClass = attacker:GetClass()
+
+ if ( attacker:IsPlayer() ) then
+
+ net.Start( "ACF_PlayerKilledNPC" )
+
+ net.WriteString( ent:GetClass() )
+ net.WriteString( InflictorClass )
+ net.WriteEntity( attacker )
+
+ net.Broadcast()
+
+ return
+ end
+
+ end
+
+ if ( ent:GetClass() == "npc_turret_floor" ) then AttackerClass = ent:GetClass() end
+
+ net.Start( "ACF_NPCKilledNPC" )
+
+ net.WriteString( ent:GetClass() )
+ net.WriteString( InflictorClass )
+ net.WriteString( AttackerClass )
+
+ net.Broadcast()
+ end
+ hook.Add( "OnNPCKilled", "ACF_OnNPCKilled", ACF_OnNPCKilled )
+
+ util.AddNetworkString( "ACF_PlayerKilled" )
+ util.AddNetworkString( "ACF_PlayerKilledSelf" )
+ util.AddNetworkString( "ACF_PlayerKilledByPlayer" )
+
+ local function ACF_PlayerDeath( ply, inflictor, attacker )
+
+ if ( IsValid( attacker ) && attacker:GetClass() == "trigger_hurt" ) then attacker = ply end
+
+ if ( IsValid( attacker ) && attacker:IsVehicle() && IsValid( attacker:GetDriver() ) ) then
+ attacker = attacker:GetDriver()
+ end
+
+ if ( !IsValid( inflictor ) && IsValid( attacker ) ) then
+ inflictor = attacker
+ end
+
+ -- Convert the inflictor to the weapon that they're holding if we can.
+ -- This can be right or wrong with NPCs since combine can be holding a
+ -- pistol but kill you by hitting you with their arm.
+ local InflictorClass = "worldspawn"
+
+ if ( IsValid( inflictor ) && inflictor == attacker && ( inflictor:IsPlayer() || inflictor:IsNPC() ) ) then
+
+ inflictor = inflictor:GetActiveWeapon()
+ if ( !IsValid( inflictor ) ) then inflictor = attacker end
+ end
+
+ if inflictor.ACF and inflictor.Class and inflictor:GetClass() != "acf_ammo" then
+ InflictorClass = "acf_" .. inflictor.Class
+ else
+ InflictorClass = inflictor:GetClass()
+ end
+
+ if ( attacker == ply ) then return end
+
+ if ( attacker:IsPlayer() ) then
+
+ net.Start( "ACF_PlayerKilledByPlayer" )
+
+ net.WriteEntity( ply )
+ net.WriteString( InflictorClass )
+ net.WriteEntity( attacker )
+
+ net.Broadcast()
+
+ return
+ end
+
+ net.Start( "ACF_PlayerKilled" )
+
+ net.WriteEntity( ply )
+ net.WriteString( InflictorClass )
+ net.WriteString( attacker:GetClass() )
+
+ net.Broadcast()
+ end
+ hook.Add( "PlayerDeath", "ACF_PlayerDeath", ACF_PlayerDeath )
+ end
+end
+
+if CLIENT then
+ local IconColor = Color( 200, 200, 48, 255 )
+
+ killicon.Add( "acf_gun", "HUD/killicons/acf_gun", IconColor )
+ killicon.Add( "acf_ammo", "HUD/killicons/acf_ammo", IconColor )
+ killicon.Add( "torch", "HUD/killicons/torch", IconColor )
+
+ if ACF.EnableKillicons then
+ killicon.Add( "acf_AC", "HUD/killicons/acf_AC", IconColor )
+ killicon.Add( "acf_AL", "HUD/killicons/acf_AL", IconColor )
+ killicon.Add( "acf_C", "HUD/killicons/acf_C", IconColor )
+ killicon.Add( "acf_GL", "HUD/killicons/acf_GL", IconColor )
+ killicon.Add( "acf_HMG", "HUD/killicons/acf_HMG", IconColor )
+ killicon.Add( "acf_HW", "HUD/killicons/acf_HW", IconColor )
+ killicon.Add( "acf_MG", "HUD/killicons/acf_MG", IconColor )
+ killicon.Add( "acf_MO", "HUD/killicons/acf_MO", IconColor )
+ killicon.Add( "acf_RAC", "HUD/killicons/acf_RAC", IconColor )
+ killicon.Add( "acf_SA", "HUD/killicons/acf_SA", IconColor )
+
+ local function doNothing()
+ return false
+ end
+
+ net.Receive( "PlayerKilledByPlayer", doNothing )
+ net.Receive( "PlayerKilled", doNothing )
+
+ net.Receive( "PlayerKilledNPC", doNothing )
+ net.Receive( "NPCKilledNPC", doNothing )
+
+ local function RecvPlayerKilledByPlayer()
+
+ local victim = net.ReadEntity()
+ local inflictor = net.ReadString()
+ local attacker = net.ReadEntity()
+
+ if ( !IsValid( attacker ) ) then return end
+ if ( !IsValid( victim ) ) then return end
+
+ GAMEMODE:AddDeathNotice( attacker:Name(), attacker:Team(), inflictor, victim:Name(), victim:Team() )
+
+ end
+ net.Receive( "ACF_PlayerKilledByPlayer", RecvPlayerKilledByPlayer )
+
+ local function RecvPlayerKilledSelf()
+
+ local victim = net.ReadEntity()
+ if ( !IsValid( victim ) ) then return end
+ GAMEMODE:AddDeathNotice( nil, 0, "suicide", victim:Name(), victim:Team() )
+
+ end
+ net.Receive( "ACF_PlayerKilledSelf", RecvPlayerKilledSelf )
+
+ local function RecvPlayerKilled()
+
+ local victim = net.ReadEntity()
+ if ( !IsValid( victim ) ) then return end
+ local inflictor = net.ReadString()
+ local attacker = "#" .. net.ReadString()
+
+ GAMEMODE:AddDeathNotice( attacker, -1, inflictor, victim:Name(), victim:Team() )
+
+ end
+ net.Receive( "ACF_PlayerKilled", RecvPlayerKilled )
+
+ local function RecvPlayerKilledNPC()
+
+ local victimtype = net.ReadString()
+ local victim = "#" .. victimtype
+ local inflictor = net.ReadString()
+ local attacker = net.ReadEntity()
+
+ --
+ -- For some reason the killer isn't known to us, so don't proceed.
+ --
+ if ( !IsValid( attacker ) ) then return end
+
+ GAMEMODE:AddDeathNotice( attacker:Name(), attacker:Team(), inflictor, victim, -1 )
+
+ local bIsLocalPlayer = ( IsValid(attacker) && attacker == LocalPlayer() )
+
+ local bIsEnemy = IsEnemyEntityName( victimtype )
+ local bIsFriend = IsFriendEntityName( victimtype )
+
+ if ( bIsLocalPlayer && bIsEnemy ) then
+ achievements.IncBaddies()
+ end
+
+ if ( bIsLocalPlayer && bIsFriend ) then
+ achievements.IncGoodies()
+ end
+
+ if ( bIsLocalPlayer && ( !bIsFriend && !bIsEnemy ) ) then
+ achievements.IncBystander()
+ end
+
+ end
+ net.Receive( "ACF_PlayerKilledNPC", RecvPlayerKilledNPC )
+
+ local function RecvNPCKilledNPC()
+
+ local victim = "#" .. net.ReadString()
+ local inflictor = net.ReadString()
+ local attacker = "#" .. net.ReadString()
+
+ GAMEMODE:AddDeathNotice( attacker, -1, inflictor, victim, -1 )
+
+ end
+ net.Receive( "ACF_NPCKilledNPC", RecvNPCKilledNPC )
+ end
+end
diff --git a/lua/autorun/wheel_list.lua b/lua/autorun/wheel_list.lua
new file mode 100644
index 000000000..3aea4bba5
--- /dev/null
+++ b/lua/autorun/wheel_list.lua
@@ -0,0 +1,14 @@
+--[Wheel model pack by Jojobull, wheel tool list by Karbine.
+
+list.Set( "WheelModels", "models/jojobull/wheel_001.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_002.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_003.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_004.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_005.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_006.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_007.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_008.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_009.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_010.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_011.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
+list.Set( "WheelModels", "models/jojobull/wheel_012.mdl", { wheel_rx = 90, wheel_ry = 0, wheel_rz = 0} )
diff --git a/lua/effects/ACF_AP_Impact/init.lua b/lua/effects/ACF_AP_Impact/init.lua
deleted file mode 100644
index 22ce2367c..000000000
--- a/lua/effects/ACF_AP_Impact/init.lua
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
- /*---------------------------------------------------------
- Initializes the effect. The data is a table of data
- which was passed from the server.
- ---------------------------------------------------------*/
- function EFFECT:Init( data )
-
- self.Origin = data:GetOrigin()
- self.DirVec = data:GetNormal()
- self.Velocity = data:GetScale() --Mass of the projectile in kg
- self.Mass = data:GetMagnitude() --Velocity of the projectile in gmod units
- self.Emitter = ParticleEmitter( self.Origin )
-
- self.Scale = math.max(self.Mass * (self.Velocity/39.37)/100,1)^0.3
-
- --self.Entity:EmitSound( "ambient/explosions/explode_1.wav" , 100 + self.Radius*10, 200 - self.Radius*10 )
-
- local BulletEffect = {}
- BulletEffect.Num = 1
- BulletEffect.Src = self.Origin - self.DirVec
- BulletEffect.Dir = self.DirVec
- BulletEffect.Spread = Vector(0,0,0)
- BulletEffect.Tracer = 0
- BulletEffect.Force = 0
- BulletEffect.Damage = 0
- LocalPlayer():FireBullets(BulletEffect)
-
- util.Decal("ExplosiveGunshot", self.Origin + self.DirVec*10, self.Origin - self.DirVec*10)
-
- end
-
-/*---------------------------------------------------------
- THINK
----------------------------------------------------------*/
-function EFFECT:Think( )
- return false
-end
-
-/*---------------------------------------------------------
- Draw the effect
----------------------------------------------------------*/
-function EFFECT:Render()
-end
-
-
\ No newline at end of file
diff --git a/lua/effects/ACF_AP_Penetration/init.lua b/lua/effects/ACF_AP_Penetration/init.lua
deleted file mode 100644
index c5d9a295c..000000000
--- a/lua/effects/ACF_AP_Penetration/init.lua
+++ /dev/null
@@ -1,195 +0,0 @@
-
-
- /*---------------------------------------------------------
- Initializes the effect. The data is a table of data
- which was passed from the server.
- ---------------------------------------------------------*/
- function EFFECT:Init( data )
-
- self.Origin = data:GetOrigin()
- self.DirVec = data:GetNormal()
- self.Velocity = data:GetScale() --Mass of the projectile in kg
- self.Mass = data:GetMagnitude() --Velocity of the projectile in gmod units
- self.Emitter = ParticleEmitter( self.Origin )
-
- self.Scale = math.max(self.Mass * (self.Velocity/39.37)/100,1)^0.3
-
- local ImpactTr = { }
- ImpactTr.start = self.Origin - self.DirVec*20
- ImpactTr.endpos = self.Origin + self.DirVec*20
- local Impact = util.TraceLine(ImpactTr) --Trace to see if it will hit anything
- self.Normal = Impact.HitNormal
-
- --self.Entity:EmitSound( "ambient/explosions/explode_1.wav" , 100 + self.Radius*10, 200 - self.Radius*10 )
-
- -- Material Enum
- -- 65 ANTLION
- -- 66 BLOODYFLESH
- -- 67 CONCRETE / NODRAW
- -- 68 DIRT
- -- 70 FLESH
- -- 71 GRATE
- -- 72 ALIENFLESH
- -- 73 CLIP
- -- 76 PLASTIC
- -- 77 METAL
- -- 78 SAND
- -- 79 FOLIAGE
- -- 80 COMPUTER
- -- 83 SLOSH
- -- 84 TILE
- -- 86 VENT
- -- 87 WOOD
- -- 89 GLASS
-
- local Mat = Impact.MatType
- if Mat == 71 or Mat == 73 or Mat == 77 or Mat == 80 then -- Metal
- self:Metal()
- else -- Nonspecific
- self:Concrete()
- end
-
- end
-
-function EFFECT:Metal()
-
- util.Decal("Impact.Metal", self.Origin - self.DirVec*10, self.Origin + self.DirVec*10)
-
- for i=0, 4*self.Scale do
-
- local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
- if (Debris) then
- Debris:SetVelocity ( self.Normal * math.random( 20,40*self.Scale) + VectorRand() * math.random( 25,50*self.Scale) )
- Debris:SetLifeTime( 0 )
- Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Scale/3 )
- Debris:SetStartAlpha( 255 )
- Debris:SetEndAlpha( 0 )
- Debris:SetStartSize( 1*self.Scale )
- Debris:SetEndSize( 1*self.Scale )
- Debris:SetRoll( math.Rand(0, 360) )
- Debris:SetRollDelta( math.Rand(-3, 3) )
- Debris:SetAirResistance( 100 )
- Debris:SetGravity( Vector( 0, 0, -650 ) )
- Debris:SetColor( 120,120,120 )
- end
- end
-
- for i=0, 5*self.Scale do
-
- local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
- if (Embers) then
- Embers:SetVelocity ( (self.Normal - VectorRand()) * math.random(30*self.Scale,80*self.Scale) )
- Embers:SetLifeTime( 0 )
- Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Scale/5 )
- Embers:SetStartAlpha( 255 )
- Embers:SetEndAlpha( 0 )
- Embers:SetStartSize( 2*self.Scale )
- Embers:SetEndSize( 0*self.Scale )
- Embers:SetStartLength( 5*self.Scale )
- Embers:SetEndLength ( 0*self.Scale )
- Embers:SetRoll( math.Rand(0, 360) )
- Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
- Embers:SetAirResistance( 20 )
- Embers:SetGravity( VectorRand()*10 )
- Embers:SetColor( 200,200,200 )
- end
- end
-
- local Sparks = EffectData()
- Sparks:SetOrigin( self.Origin )
- Sparks:SetNormal( self.Normal )
- Sparks:SetMagnitude( self.Scale )
- Sparks:SetScale( self.Scale )
- Sparks:SetRadius( self.Scale )
- util.Effect( "Sparks", Sparks )
-
- end
-
-function EFFECT:Concrete()
-
- util.Decal("ExplosiveGunshot", self.Origin - self.DirVec*10, self.Origin + self.DirVec*10)
-
- for i=0, 4*self.Scale do
-
- local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
- if (Debris) then
- Debris:SetVelocity ( self.Normal * math.random( 20,40*self.Scale) + VectorRand() * math.random( 25,50*self.Scale) )
- Debris:SetLifeTime( 0 )
- Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Scale/3 )
- Debris:SetStartAlpha( 255 )
- Debris:SetEndAlpha( 0 )
- Debris:SetStartSize( 1*self.Scale )
- Debris:SetEndSize( 1*self.Scale )
- Debris:SetRoll( math.Rand(0, 360) )
- Debris:SetRollDelta( math.Rand(-3, 3) )
- Debris:SetAirResistance( 100 )
- Debris:SetGravity( Vector( 0, 0, -650 ) )
- Debris:SetColor( 120,120,120 )
- end
- end
-
- for i=0, 3*self.Scale do
-
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Smoke) then
- Smoke:SetVelocity( self.Normal * math.random( 20,40*self.Scale) + VectorRand() * math.random( 25,50*self.Scale) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Scale/3 )
- Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 1*self.Scale )
- Smoke:SetEndSize( 2*self.Scale )
- Smoke:SetRoll( math.Rand(150, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 200 )
- Smoke:SetGravity( Vector( math.random(-5,5)*self.Scale, math.random(-5,5)*self.Scale, -50 ) )
- Smoke:SetColor( 90,90,90 )
- end
-
- end
-
- for i=0, 5*self.Scale do
-
- local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
- if (Embers) then
- Embers:SetVelocity ( (self.Normal - VectorRand()) * math.random(30*self.Scale,80*self.Scale) )
- Embers:SetLifeTime( 0 )
- Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Scale/5 )
- Embers:SetStartAlpha( 255 )
- Embers:SetEndAlpha( 0 )
- Embers:SetStartSize( 5*self.Scale )
- Embers:SetEndSize( 0*self.Scale )
- Embers:SetStartLength( 5*self.Scale )
- Embers:SetEndLength ( 0*self.Scale )
- Embers:SetRoll( math.Rand(0, 360) )
- Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
- Embers:SetAirResistance( 20 )
- Embers:SetGravity( VectorRand()*10 )
- Embers:SetColor( 200,200,200 )
- end
- end
-
- local Sparks = EffectData()
- Sparks:SetOrigin( self.Origin )
- Sparks:SetNormal( self.Normal )
- Sparks:SetMagnitude( self.Scale )
- Sparks:SetScale( self.Scale )
- Sparks:SetRadius( self.Scale )
- util.Effect( "Sparks", Sparks )
-
- end
-
-/*---------------------------------------------------------
- THINK
----------------------------------------------------------*/
-function EFFECT:Think( )
- return false
-end
-
-/*---------------------------------------------------------
- Draw the effect
----------------------------------------------------------*/
-function EFFECT:Render()
-end
-
-
\ No newline at end of file
diff --git a/lua/effects/ACF_AP_Ricochet/init.lua b/lua/effects/ACF_AP_Ricochet/init.lua
deleted file mode 100644
index c2f3b04c6..000000000
--- a/lua/effects/ACF_AP_Ricochet/init.lua
+++ /dev/null
@@ -1,46 +0,0 @@
-
-
- /*---------------------------------------------------------
- Initializes the effect. The data is a table of data
- which was passed from the server.
- ---------------------------------------------------------*/
- function EFFECT:Init( data )
-
- self.Origin = data:GetOrigin()
- self.DirVec = data:GetNormal()
- self.Velocity = data:GetScale() --Velocity of the projectile in gmod units
- self.Mass = data:GetMagnitude() --Mass of the projectile in kg
- self.Emitter = ParticleEmitter( self.Origin )
-
- self.Scale = math.max(self.Mass * (self.Velocity/39.37)/100,1)^0.3
-
- --self.Entity:EmitSound( "ambient/explosions/explode_1.wav" , 100 + self.Radius*10, 200 - self.Radius*10 )
-
- local BulletEffect = {}
- BulletEffect.Num = 1
- BulletEffect.Src = self.Origin - self.DirVec
- BulletEffect.Dir = self.DirVec
- BulletEffect.Spread = Vector(0,0,0)
- BulletEffect.Tracer = 0
- BulletEffect.Force = 0
- BulletEffect.Damage = 0
- LocalPlayer():FireBullets(BulletEffect)
-
- util.Decal("ExplosiveGunshot", self.Origin + self.DirVec*10, self.Origin - self.DirVec*10)
-
- end
-
-/*---------------------------------------------------------
- THINK
----------------------------------------------------------*/
-function EFFECT:Think( )
- return false
-end
-
-/*---------------------------------------------------------
- Draw the effect
----------------------------------------------------------*/
-function EFFECT:Render()
-end
-
-
\ No newline at end of file
diff --git a/lua/effects/ACF_BulletEffect/init.lua b/lua/effects/ACF_BulletEffect/init.lua
deleted file mode 100644
index 70f4dfd43..000000000
--- a/lua/effects/ACF_BulletEffect/init.lua
+++ /dev/null
@@ -1,188 +0,0 @@
-
-function EFFECT:Init( data )
-
- self.Index = data:GetAttachment()
- self:SetModel("models/munitions/round_100mm_shot.mdl")
-
- if not ( self.Index ) then
- Msg("ACF_BulletEffect: Error! Insufficient data to spawn.\n")
- self:Remove()
- return
- end
- self.CreateTime = CurTime()
-
- local Hit = data:GetScale()
- local Bullet = ACF.BulletEffect[self.Index]
-
- if (Hit > 0 and Bullet) then --Scale encodes the hit type, so if it's 0 it's a new bullet, else it's an update so we need to remove the effect
-
- --print("Updating Bullet Effect")
- Bullet.SimFlight = data:GetStart()*10 --Updating old effect with new values
- Bullet.SimPos = data:GetOrigin()
-
- if (Hit == 1) then --Bullet has reached end of flight, remove old effect
-
- self.HitEnd = ACF.RoundTypes[Bullet.AmmoType]["endeffect"]
- self:HitEnd( Bullet )
- ACF.BulletEffect[self.Index] = nil --This is crucial, to effectively remove the bullet flight model from the client
-
- elseif (Hit == 2) then --Bullet penetrated, don't remove old effect
-
- self.HitPierce = ACF.RoundTypes[Bullet.AmmoType]["pierceeffect"]
- self:HitPierce( Bullet )
-
- elseif (Hit == 3) then --Bullet ricocheted, don't remove old effect
-
- self.HitRicochet = ACF.RoundTypes[Bullet.AmmoType]["ricocheteffect"]
- self:HitRicochet( Bullet )
-
- end
- ACF_SimBulletFlight( Bullet, self.Index )
- self:Remove() --This effect updated the old one, so it removes itself now
-
- else
- --print("Creating Bullet Effect")
- local BulletData = {}
- BulletData.Crate = Entity(math.Round(data:GetMagnitude()))
- BulletData.SimFlight = data:GetStart()*10
- BulletData.SimPos = data:GetOrigin()
- BulletData.Caliber = BulletData.Crate:GetNetworkedInt( "Caliber" ) or 10
- BulletData.RoundMass = BulletData.Crate:GetNetworkedInt( "ProjMass" ) or 10
- BulletData.FillerMass = BulletData.Crate:GetNetworkedInt( "FillerMass" ) or 0
- BulletData.DragCoef = BulletData.Crate:GetNetworkedInt( "DragCoef" ) or 1
- BulletData.AmmoType = BulletData.Crate:GetNetworkedString( "AmmoType" )
- if BulletData.AmmoType == "" then BulletData.AmmoType = "AP" end
-
- if BulletData.Crate:GetNetworkedInt( "Tracer" ) > 0 then
- BulletData.Tracer = ParticleEmitter( BulletData.SimPos )
- local col = BulletData.Crate:GetColor()
- BulletData.TracerColour = Vector(col.r,col.g,col.b)
-
- end
-
-
- BulletData.Accel = BulletData.Crate:GetNetworkedVector( "Accel" ) or Vector(0,0,600*-1)
-
- BulletData.LastThink = CurTime()
- BulletData.Effect = self.Entity
-
- ACF.BulletEffect[self.Index] = BulletData --Add all that data to the bullet table, overwriting if needed
-
- self:SetPos( BulletData.SimPos ) --Moving the effect to the calculated position
- self:SetAngles( BulletData.SimFlight:Angle() )
-
- ACF_SimBulletFlight( ACF.BulletEffect[self.Index], self.Index )
-
- end
-
-end
-
-function EFFECT:HitEnd()
- --You overwrite this with your own function, defined in the ammo definition file
- ACF.BulletEffect[self.Index] = nil --Failsafe
-end
-
-function EFFECT:HitPierce()
- --You overwrite this with your own function, defined in the ammo definition file
- ACF.BulletEffect[self.Index] = nil --Failsafe
-end
-
-function EFFECT:HitRicochet()
- --You overwrite this with your own function, defined in the ammo definition file
- ACF.BulletEffect[self.Index] = nil --Failsafe
-end
-
-function EFFECT:Think()
-
- local Bullet = ACF.BulletEffect[self.Index]
- if Bullet and self.CreateTime > CurTime()-30 then
- return true
- else
- self:Remove()
- return false
- end
-
-end
-
-function EFFECT:ApplyMovement( Bullet )
-
- self:SetPos( Bullet.SimPos ) --Moving the effect to the calculated position
- self:SetAngles( Bullet.SimFlight:Angle() )
-
- if Bullet.Tracer then
- local DeltaTime = CurTime() - Bullet.LastThink
- local DeltaPos = Bullet.SimFlight*DeltaTime
- local Length = math.max(DeltaPos:Length()*2,1)
- for i=1, 5 do
- local Light = Bullet.Tracer:Add( "sprites/light_glow02_add.vmt", Bullet.SimPos - (DeltaPos*i/5) )
- if (Light) then
- Light:SetAngles( Bullet.SimFlight:Angle() )
- Light:SetVelocity( Bullet.SimFlight:GetNormalized() )
- Light:SetColor( Bullet.TracerColour.x, Bullet.TracerColour.y, Bullet.TracerColour.z )
- Light:SetDieTime( 0.1 )
- Light:SetStartAlpha( 255 )
- Light:SetEndAlpha( 155 )
- Light:SetStartSize( 5*Bullet.Caliber )
- Light:SetEndSize( 1 )
- Light:SetStartLength( Length )
- Light:SetEndLength( 1 )
- end
- local Smoke = Bullet.Tracer:Add( "particle/smokesprites_000"..math.random(1,9), Bullet.SimPos - (DeltaPos*i/5) )
- if (Smoke) then
- Smoke:SetAngles( Bullet.SimFlight:Angle() )
- --Smoke:SetVelocity( Vector(0,0,0) )
- Smoke:SetColor( 200 , 200 , 200 )
- Smoke:SetDieTime( 1.2 )
- Smoke:SetStartAlpha( 10 )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 1 )
- Smoke:SetEndSize( Length/400*Bullet.Caliber )
- Smoke:SetRollDelta( 0.1 )
- Smoke:SetAirResistance( 100 )
- --Smoke:SetGravity( VectorRand()*5 )
- --Smoke:SetCollide( 0 )
- --Smoke:SetLighting( 0 )
- end
- end
- end
-
-end
-
--- function EFFECT:HitEffect( HitPos, Energy, EffectType ) --EffectType key : 1 = Round stopped, 2 = Round penetration
-
- -- if (EffectType > 0) then
- -- local BulletEffect = {}
- -- BulletEffect.Num = 1
- -- BulletEffect.Src = HitPos - self.SimFlight:GetNormalized()*20
- -- BulletEffect.Dir = self.SimFlight
- -- BulletEffect.Spread = Vector(0,0,0)
- -- BulletEffect.Tracer = 0
- -- BulletEffect.Force = 0
- -- BulletEffect.Damage = 0
- -- self.Entity:FireBullets(BulletEffect)
- -- end
- -- if (EffectType == 2) then
- -- local Spall = EffectData()
- -- Spall:SetOrigin( HitPos )
- -- Spall:SetNormal( (self.SimFlight):GetNormalized() )
- -- Spall:SetScale( math.max(Energy/5000,1) )
- -- util.Effect( "AP_Hit", Spall )
- -- elseif (EffectType == 3) then
- -- local Sparks = EffectData()
- -- Sparks:SetOrigin( HitPos )
- -- Sparks:SetNormal( (self.SimFlight):GetNormalized() )
- -- util.Effect( "ManhackSparks", Sparks )
- -- end
-
--- end
-
-function EFFECT:Render()
-
- local Bullet = ACF.BulletEffect[self.Index]
-
- if (Bullet) then
- self.Entity:SetModelScale( Bullet.Caliber/10 , 0 )
- self.Entity:DrawModel() // Draw the model.
- end
-
-end
\ No newline at end of file
diff --git a/lua/effects/ACF_HEAT_Explosion/init.lua b/lua/effects/ACF_HEAT_Explosion/init.lua
deleted file mode 100644
index a0ae17dbe..000000000
--- a/lua/effects/ACF_HEAT_Explosion/init.lua
+++ /dev/null
@@ -1,95 +0,0 @@
-
-
- /*---------------------------------------------------------
- Initializes the effect. The data is a table of data
- which was passed from the server.
- ---------------------------------------------------------*/
-function EFFECT:Init( data )
-
- self.Origin = data:GetOrigin()
- self.DirVec = data:GetNormal()
- self.Radius = math.max(data:GetRadius()/50,1)
- self.Emitter = ParticleEmitter( self.Origin )
-
- for i=0, 3*self.Radius do
-
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Smoke) then
- Smoke:SetVelocity( (-self.DirVec + VectorRand()/10) * math.random(50,130*self.Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
- Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 2*self.Radius )
- Smoke:SetEndSize( 15*self.Radius )
- Smoke:SetRoll( math.Rand(150, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 300 )
- Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -450 ) )
- Smoke:SetColor( 160,160,160)
- end
-
- end
-
- for i=0, 4*self.Radius do
-
- local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
- if (Debris) then
- Debris:SetVelocity ( (self.DirVec + VectorRand()/10) * math.random(250*self.Radius,450*self.Radius) )
- Debris:SetLifeTime( 0 )
- Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Radius/3 )
- Debris:SetStartAlpha( 255 )
- Debris:SetEndAlpha( 0 )
- Debris:SetStartSize( 0.3*self.Radius )
- Debris:SetEndSize( 0.3*self.Radius )
- Debris:SetRoll( math.Rand(0, 360) )
- Debris:SetRollDelta( math.Rand(-3, 3) )
- Debris:SetAirResistance( 200 )
- Debris:SetGravity( Vector( 0, 0, -650 ) )
- Debris:SetColor( 120,120,120 )
- end
- end
-
- for i=0, 5*self.Radius do
-
- local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
- if (Embers) then
- Embers:SetVelocity ( (self.DirVec + VectorRand()/10) * math.random(50*self.Radius,300*self.Radius) )
- Embers:SetLifeTime( 0 )
- Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Radius/3 )
- Embers:SetStartAlpha( 255 )
- Embers:SetEndAlpha( 0 )
- Embers:SetStartSize( 1*self.Radius )
- Embers:SetEndSize( 0*self.Radius )
- Embers:SetStartLength( 5*self.Radius )
- Embers:SetEndLength ( 0*self.Radius )
- Embers:SetRoll( math.Rand(0, 360) )
- Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
- Embers:SetAirResistance( 20 )
- Embers:SetGravity( Vector( 0, 0, -650 ) )
- Embers:SetColor( 200,200,200 )
- end
- end
-
- local Flash = EffectData()
- Flash:SetOrigin( self.Origin )
- Flash:SetScale( self.Radius )
- Flash:SetNormal( self.DirVec )
- util.Effect( "ACF_Scaled_Explosion", Flash )
-
- end
-
-/*---------------------------------------------------------
- THINK
----------------------------------------------------------*/
-function EFFECT:Think( )
-
-end
-
-/*---------------------------------------------------------
- Draw the effect
----------------------------------------------------------*/
-function EFFECT:Render()
-end
-
-
diff --git a/lua/effects/ACF_MuzzleFlash/init.lua b/lua/effects/ACF_MuzzleFlash/init.lua
deleted file mode 100644
index 4d8a99e6d..000000000
--- a/lua/effects/ACF_MuzzleFlash/init.lua
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
- /*---------------------------------------------------------
- Initializes the effect. The data is a table of data
- which was passed from the server.
- ---------------------------------------------------------*/
- function EFFECT:Init( data )
-
- local Gun = data:GetEntity()
- local Propellant = data:GetScale()
- local ReloadTime = data:GetMagnitude()
- local Class = Gun:GetNWString( "Class" )
- local RoundType = ACF.IdRounds[data:GetSurfaceProp()]
-
- if Gun:IsValid() then
- if Propellant > 0 then
- local SoundPressure = (Propellant*1000)^0.5
- sound.Play( ACF.Classes["GunClass"][Class]["sound"], Gun:GetPos() , math.Clamp(SoundPressure,75,255), math.Clamp(100,15,255))
- sound.Play( ACF.Classes["GunClass"][Class]["sound"], Gun:GetPos() , math.Clamp(SoundPressure,75,255), math.Clamp(100,15,255))
- sound.Play( ACF.Classes["GunClass"][Class]["soundDistance"], Gun:GetPos() , math.Clamp(SoundPressure,75,255), math.Clamp(100,15,255))
- sound.Play( ACF.Classes["GunClass"][Class]["soundNormal"], Gun:GetPos() , math.Clamp(SoundPressure,75,255), math.Clamp(100,15,255))
-
-
-
- local Muzzle = Gun:GetAttachment( Gun:LookupAttachment( "muzzle" ) )
- ParticleEffect( ACF.Classes["GunClass"][Class]["muzzleflash"], Muzzle.Pos, Muzzle.Ang, Gun )
- Gun:Animate( Class, ReloadTime, false )
- else
- Gun:Animate( Class, ReloadTime, true )
- end
- end
-
- end
-
-
-/*---------------------------------------------------------
- THINK
----------------------------------------------------------*/
-function EFFECT:Think( )
- return false
-end
-
-/*---------------------------------------------------------
- Draw the effect
----------------------------------------------------------*/
-function EFFECT:Render()
-end
\ No newline at end of file
diff --git a/lua/effects/ACF_Scaled_Explosion/init.lua b/lua/effects/ACF_Scaled_Explosion/init.lua
deleted file mode 100644
index bd3414dcd..000000000
--- a/lua/effects/ACF_Scaled_Explosion/init.lua
+++ /dev/null
@@ -1,356 +0,0 @@
-
-
- /*---------------------------------------------------------
- Initializes the effect. The data is a table of data
- which was passed from the server.
- ---------------------------------------------------------*/
-function EFFECT:Init( data )
-
- self.Origin = data:GetOrigin()
- self.DirVec = data:GetNormal()
- self.Radius = math.max(data:GetRadius()/50,1)
- self.Emitter = ParticleEmitter( self.Origin )
-
- local ImpactTr = { }
- ImpactTr.start = self.Origin - self.DirVec*20
- ImpactTr.endpos = self.Origin + self.DirVec*20
- local Impact = util.TraceLine(ImpactTr) --Trace to see if it will hit anything
- self.Normal = Impact.HitNormal
-
- local GroundTr = { }
- GroundTr.start = self.Origin + Vector(0,0,1)
- GroundTr.endpos = self.Origin - Vector(0,0,1)*self.Radius*20
- GroundTr.mask = 131083
- local Ground = util.TraceLine(GroundTr)
-
- -- Material Enum
- -- 65 ANTLION
- -- 66 BLOODYFLESH
- -- 67 CONCRETE / NODRAW
- -- 68 DIRT
- -- 70 FLESH
- -- 71 GRATE
- -- 72 ALIENFLESH
- -- 73 CLIP
- -- 76 PLASTIC
- -- 77 METAL
- -- 78 SAND
- -- 79 FOLIAGE
- -- 80 COMPUTER
- -- 83 SLOSH
- -- 84 TILE
- -- 86 VENT
- -- 87 WOOD
- -- 89 GLASS
-
- local Mat = Impact.MatType
- local SmokeColor = Vector(90,90,90)
- if Impact.HitSky or not Impact.Hit then
- SmokeColor = Vector(90,90,90)
- self:Airburst( SmokeColor )
- elseif Mat == 71 or Mat == 73 or Mat == 77 or Mat == 80 then -- Metal
- SmokeColor = Vector(170,170,170)
- self:Metal( SmokeColor )
- elseif Mat == 68 or Mat == 79 then -- Dirt
- SmokeColor = Vector(100,80,50)
- self:Dirt( SmokeColor )
- elseif Mat == 78 then -- Sand
- SmokeColor = Vector(100,80,50)
- self:Sand( SmokeColor )
- else -- Nonspecific
- SmokeColor = Vector(90,90,90)
- self:Concrete( SmokeColor )
- end
-
- if Ground.HitWorld then
- self:Shockwave( Ground, SmokeColor )
- end
-
- end
-
-function EFFECT:Core()
-
- for i=0, 2*self.Radius do
-
- local Flame = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin)
- if (Flame) then
- Flame:SetVelocity( VectorRand() * math.random(50,150*self.Radius) )
- Flame:SetLifeTime( 0 )
- Flame:SetDieTime( 0.15 )
- Flame:SetStartAlpha( math.Rand( 50, 255 ) )
- Flame:SetEndAlpha( 0 )
- Flame:SetStartSize( 2.5*self.Radius )
- Flame:SetEndSize( 15*self.Radius )
- Flame:SetRoll( math.random(120, 360) )
- Flame:SetRollDelta( math.Rand(-1, 1) )
- Flame:SetAirResistance( 300 )
- Flame:SetGravity( Vector( 0, 0, 4 ) )
- Flame:SetColor( 255,255,255 )
- end
-
- end
-
- for i=0, 4*self.Radius do
-
- local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
- if (Debris) then
- Debris:SetVelocity ( VectorRand() * math.random(150*self.Radius,250*self.Radius) )
- Debris:SetLifeTime( 0 )
- Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Radius/3 )
- Debris:SetStartAlpha( 255 )
- Debris:SetEndAlpha( 0 )
- Debris:SetStartSize( 1*self.Radius )
- Debris:SetEndSize( 1*self.Radius )
- Debris:SetRoll( math.Rand(0, 360) )
- Debris:SetRollDelta( math.Rand(-3, 3) )
- Debris:SetAirResistance( 10 )
- Debris:SetGravity( Vector( 0, 0, -650 ) )
- Debris:SetColor( 120,120,120 )
- end
- end
-
- for i=0, 5*self.Radius do
-
- local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
- if (Embers) then
- Embers:SetVelocity ( VectorRand() * math.random(70*self.Radius,160*self.Radius) )
- Embers:SetLifeTime( 0 )
- Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Radius/3 )
- Embers:SetStartAlpha( 255 )
- Embers:SetEndAlpha( 0 )
- Embers:SetStartSize( 1*self.Radius )
- Embers:SetEndSize( 0*self.Radius )
- Embers:SetStartLength( 5*self.Radius )
- Embers:SetEndLength ( 0*self.Radius )
- Embers:SetRoll( math.Rand(0, 360) )
- Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
- Embers:SetAirResistance( 20 )
- Embers:SetGravity( Vector( 0, 0, -650 ) )
- Embers:SetColor( 200,200,200 )
- end
- end
-
- for i=0, 2*self.Radius do
- local Whisp = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Whisp) then
- Whisp:SetVelocity(VectorRand() * math.random( 150,250*self.Radius) )
- Whisp:SetLifeTime( 0 )
- Whisp:SetDieTime( math.Rand( 3 , 5 )*self.Radius/3 )
- Whisp:SetStartAlpha( math.Rand( 20, 50 ) )
- Whisp:SetEndAlpha( 0 )
- Whisp:SetStartSize( 10*self.Radius )
- Whisp:SetEndSize( 80*self.Radius )
- Whisp:SetRoll( math.Rand(150, 360) )
- Whisp:SetRollDelta( math.Rand(-0.2, 0.2) )
- Whisp:SetAirResistance( 100 )
- Whisp:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, 0 ) )
- Whisp:SetColor( 150,150,150 )
- end
- end
-
- if self.Radius > 4 then
- for i=0, 0.5*self.Radius do
- local Cookoff = EffectData()
- Cookoff:SetOrigin( self.Origin )
- Cookoff:SetScale( self.Radius/6 )
- util.Effect( "ACF_Cookoff", Cookoff )
- end
- end
- sound.Play( "ambient/explosions/explode_5.wav", self.Origin , math.Clamp(self.Radius*10,75,165), math.Clamp(300 - self.Radius*12,15,255))
- sound.Play( "ambient/explosions/explode_4.wav", self.Origin , math.Clamp(self.Radius*10,75,165), math.Clamp(300 - self.Radius*25,15,255))
-
-end
-
-function EFFECT:Shockwave( Ground, SmokeColor )
-
- local Mat = Ground.MatType
- local Radius = (1-Ground.Fraction)*self.Radius
- local Density = 15*Radius
- local Angle = Ground.HitNormal:Angle()
- for i=0, Density do
-
- Angle:RotateAroundAxis(Angle:Forward(), (360/Density))
- local ShootVector = Angle:Up()
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), Ground.HitPos )
- if (Smoke) then
- Smoke:SetVelocity( ShootVector * math.Rand(5,200*Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*Radius /3 )
- Smoke:SetStartAlpha( math.Rand( 50, 120 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 4*Radius )
- Smoke:SetEndSize( 15*Radius )
- Smoke:SetRoll( math.Rand(0, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 200 )
- Smoke:SetGravity( Vector( math.Rand( -20 , 20 ), math.Rand( -20 , 20 ), math.Rand( 10 , 100 ) ) )
- Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
-
- end
-
-end
-
-function EFFECT:Metal( SmokeColor )
-
- self:Core()
-
- for i=0, 3*self.Radius do
-
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Smoke) then
- Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
- Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 5*self.Radius )
- Smoke:SetEndSize( 30*self.Radius )
- Smoke:SetRoll( math.Rand(150, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 100 )
- Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
- Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
-
- end
-
-end
-
-function EFFECT:Concrete( SmokeColor )
-
- self:Core()
-
- for i=0, 3*self.Radius do
-
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Smoke) then
- Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
- Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 5*self.Radius )
- Smoke:SetEndSize( 30*self.Radius )
- Smoke:SetRoll( math.Rand(150, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 100 )
- Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
- Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
-
- end
-
-end
-
-function EFFECT:Dirt( SmokeColor )
-
- self:Core()
-
- for i=0, 3*self.Radius do
-
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Smoke) then
- Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
- Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 5*self.Radius )
- Smoke:SetEndSize( 30*self.Radius )
- Smoke:SetRoll( math.Rand(150, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 100 )
- Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
- Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
-
- end
-
-end
-
-function EFFECT:Sand( SmokeColor )
-
- self:Core()
-
- for i=0, 3*self.Radius do
-
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Smoke) then
- Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
- Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 5*self.Radius )
- Smoke:SetEndSize( 30*self.Radius )
- Smoke:SetRoll( math.Rand(150, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 100 )
- Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
- Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
-
- end
-
-end
-
-function EFFECT:Airburst( SmokeColor )
-
- self:Core()
-
- for i=0, 3*self.Radius do
-
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Smoke) then
- Smoke:SetVelocity( VectorRand() * math.random( 25,50*self.Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
- Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 5*self.Radius )
- Smoke:SetEndSize( 30*self.Radius )
- Smoke:SetRoll( math.Rand(150, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 100 )
- Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
- Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
-
- end
-
- for i=0, 10*self.Radius do
-
- local AirBurst = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (AirBurst) then
- AirBurst:SetVelocity( VectorRand() * math.random( 150,200*self.Radius) )
- AirBurst:SetLifeTime( 0 )
- AirBurst:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
- AirBurst:SetStartAlpha( math.Rand( 100, 255 ) )
- AirBurst:SetEndAlpha( 0 )
- AirBurst:SetStartSize( 6*self.Radius )
- AirBurst:SetEndSize( 35*self.Radius )
- AirBurst:SetRoll( math.Rand(150, 360) )
- AirBurst:SetRollDelta( math.Rand(-0.2, 0.2) )
- AirBurst:SetAirResistance( 200 )
- AirBurst:SetGravity( Vector( math.random(-10,10)*self.Radius, math.random(-10,10)*self.Radius, 20 ) )
- AirBurst:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
- end
-
-end
-
-/*---------------------------------------------------------
- THINK
----------------------------------------------------------*/
-function EFFECT:Think( )
-
-end
-
-/*---------------------------------------------------------
- Draw the effect
----------------------------------------------------------*/
-function EFFECT:Render()
-end
-
-
diff --git a/lua/effects/ACF_Smoke/init.lua b/lua/effects/ACF_Smoke/init.lua
deleted file mode 100644
index c726a50b4..000000000
--- a/lua/effects/ACF_Smoke/init.lua
+++ /dev/null
@@ -1,105 +0,0 @@
-
-
- /*---------------------------------------------------------
- Initializes the effect. The data is a table of data
- which was passed from the server.
- ---------------------------------------------------------*/
-function EFFECT:Init( data )
-
- self.Origin = data:GetOrigin()
- self.DirVec = data:GetNormal()
- self.Radius = math.max(data:GetRadius()/50,1)
- self.Emitter = ParticleEmitter( self.Origin )
-
- local ImpactTr = { }
- ImpactTr.start = self.Origin - self.DirVec*20
- ImpactTr.endpos = self.Origin + self.DirVec*20
- local Impact = util.TraceLine(ImpactTr) --Trace to see if it will hit anything
- self.Normal = Impact.HitNormal
-
- local GroundTr = { }
- GroundTr.start = self.Origin + Vector(0,0,1)
- GroundTr.endpos = self.Origin - Vector(0,0,1)*self.Radius*20
- GroundTr.mask = 131083
- local Ground = util.TraceLine(GroundTr)
-
- local SmokeColor = Vector(255,255,255)
- if Ground.HitWorld then
- self:Shockwave( Ground, SmokeColor )
- end
-
- end
-
-function EFFECT:Core()
-
-
-
- for i=0, 2*self.Radius do
- local Whisp = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
- if (Whisp) then
- Whisp:SetVelocity(VectorRand() * math.random( 150,250*self.Radius) )
- Whisp:SetLifeTime( 0 )
- Whisp:SetDieTime( math.Rand( 3 , 5 )*self.Radius/3 )
- Whisp:SetStartAlpha( math.Rand( 0, 0 ) )
- Whisp:SetEndAlpha( 0 )
- Whisp:SetStartSize( 10*self.Radius )
- Whisp:SetEndSize( 80*self.Radius )
- Whisp:SetRoll( math.Rand(150, 360) )
- Whisp:SetRollDelta( math.Rand(-0.2, 0.2) )
- Whisp:SetAirResistance( 100 )
- Whisp:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, 0 ) )
- Whisp:SetColor( 150,150,150 )
- end
- end
-
-
- sound.Play( "ambient/explosions/explode_5.wav", self.Origin , math.Clamp(self.Radius*10,75,165), math.Clamp(300 - self.Radius*12,15,255))
- sound.Play( "ambient/explosions/explode_4.wav", self.Origin , math.Clamp(self.Radius*10,75,165), math.Clamp(300 - self.Radius*25,15,255))
-
-end
-
-function EFFECT:Shockwave( Ground, SmokeColor )
-
- local Mat = Ground.MatType
- local Radius = (1-Ground.Fraction)*self.Radius
- local Density = 7*Radius
- local Angle = Ground.HitNormal:Angle()
- for i=0, Density do
-
- Angle:RotateAroundAxis(Angle:Forward(), (360/Density))
- local ShootVector = Angle:Up()
- local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), Ground.HitPos )
- if (Smoke) then
- Smoke:SetVelocity( ShootVector * math.Rand(5,200*Radius) )
- Smoke:SetLifeTime( 0 )
- Smoke:SetDieTime( math.Rand( 20 , 20 )*Radius /3 )
- Smoke:SetStartAlpha( math.Rand( 10, 30 ) )
- Smoke:SetEndAlpha( 0 )
- Smoke:SetStartSize( 200*Radius )
- Smoke:SetEndSize( 500*Radius )
- Smoke:SetRoll( math.Rand(0, 360) )
- Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
- Smoke:SetAirResistance( 200 )
- Smoke:SetGravity( Vector( math.Rand( -20 , 20 ), math.Rand( -20 , 20 ), math.Rand( 10 , 100 ) ) )
- Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
- end
-
- end
-
-end
-
-
-/*---------------------------------------------------------
- THINK
----------------------------------------------------------*/
-function EFFECT:Think( )
-
-end
-
-/*---------------------------------------------------------
- Draw the effect
----------------------------------------------------------*/
-function EFFECT:Render()
-end
-
-
diff --git a/lua/effects/acf_ap_impact/init.lua b/lua/effects/acf_ap_impact/init.lua
new file mode 100644
index 000000000..a9c9fd233
--- /dev/null
+++ b/lua/effects/acf_ap_impact/init.lua
@@ -0,0 +1,48 @@
+
+
+ /*---------------------------------------------------------
+ Initializes the effect. The data is a table of data
+ which was passed from the server.
+ ---------------------------------------------------------*/
+ function EFFECT:Init( data )
+
+ self.Ent = data:GetEntity()
+ self.Caliber = self.Ent:GetNWFloat( "Caliber", 10 )
+ self.Origin = data:GetOrigin()
+ self.DirVec = data:GetNormal()
+ self.Velocity = data:GetScale() --Mass of the projectile in kg
+ self.Mass = data:GetMagnitude() --Velocity of the projectile in gmod units
+ self.Emitter = ParticleEmitter( self.Origin )
+
+ self.Scale = math.max(self.Mass * (self.Velocity/39.37)/100,1)^0.3
+
+ --self.Entity:EmitSound( "ambient/explosions/explode_1.wav" , 100 + self.Radius*10, 200 - self.Radius*10 )
+
+ local BulletEffect = {}
+ BulletEffect.Num = 1
+ BulletEffect.Src = self.Origin - self.DirVec
+ BulletEffect.Dir = self.DirVec
+ BulletEffect.Spread = Vector(0,0,0)
+ BulletEffect.Tracer = 0
+ BulletEffect.Force = 0
+ BulletEffect.Damage = 0
+ LocalPlayer():FireBullets(BulletEffect)
+
+ util.Decal("GunShot1", self.Origin + self.DirVec*10, self.Origin - self.DirVec*10)
+
+ end
+
+/*---------------------------------------------------------
+ THINK
+---------------------------------------------------------*/
+function EFFECT:Think( )
+ return false
+end
+
+/*---------------------------------------------------------
+ Draw the effect
+---------------------------------------------------------*/
+function EFFECT:Render()
+end
+
+
\ No newline at end of file
diff --git a/lua/effects/acf_ap_penetration/init.lua b/lua/effects/acf_ap_penetration/init.lua
new file mode 100644
index 000000000..6469dc7b6
--- /dev/null
+++ b/lua/effects/acf_ap_penetration/init.lua
@@ -0,0 +1,199 @@
+local ACFEnts = list.Get("ACFEnts")
+local GunTable = ACFEnts["Guns"]
+
+ /*---------------------------------------------------------
+ Initializes the effect. The data is a table of data
+ which was passed from the server.
+ ---------------------------------------------------------*/
+ function EFFECT:Init( data )
+
+ self.Ent = data:GetEntity()
+ self.Caliber = self.Ent:GetNWFloat( "Caliber", 10 )
+ self.Origin = data:GetOrigin()
+ self.DirVec = data:GetNormal()
+ self.Velocity = data:GetScale() --Mass of the projectile in kg
+ self.Mass = data:GetMagnitude() --Velocity of the projectile in gmod units
+ self.Emitter = ParticleEmitter( self.Origin )
+
+ self.Scale = math.max(self.Mass * (self.Velocity/39.37)/100,1)^0.3
+
+ local ImpactTr = { }
+ ImpactTr.start = self.Origin - self.DirVec*20
+ ImpactTr.endpos = self.Origin + self.DirVec*20
+ local Impact = util.TraceLine(ImpactTr) --Trace to see if it will hit anything
+ self.Normal = Impact.HitNormal
+
+ sound.Play( "/acf_other/penetratingshots/0000029"..math.random(2,5)..".wav", Impact.HitPos, math.Clamp(self.Mass*200,65,500), math.Clamp(self.Velocity*0.01,25,255), 1 )
+
+ --self.Entity:EmitSound( "ambient/explosions/explode_1.wav" , 100 + self.Radius*10, 200 - self.Radius*10 )
+
+ -- Material Enum
+ -- 65 ANTLION
+ -- 66 BLOODYFLESH
+ -- 67 CONCRETE / NODRAW
+ -- 68 DIRT
+ -- 70 FLESH
+ -- 71 GRATE
+ -- 72 ALIENFLESH
+ -- 73 CLIP
+ -- 76 PLASTIC
+ -- 77 METAL
+ -- 78 SAND
+ -- 79 FOLIAGE
+ -- 80 COMPUTER
+ -- 83 SLOSH
+ -- 84 TILE
+ -- 86 VENT
+ -- 87 WOOD
+ -- 89 GLASS
+
+ local Mat = Impact.MatType
+ if Mat == 71 or Mat == 73 or Mat == 77 or Mat == 80 then -- Metal
+ self:Metal()
+ else -- Nonspecific
+ self:Concrete()
+ end
+
+ end
+
+function EFFECT:Metal()
+ util.Decal("GunShot1", self.Origin + self.DirVec*10, self.Origin - self.DirVec*10)
+
+ for i=0, 4*self.Scale do
+
+ local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
+ if (Debris) then
+ Debris:SetVelocity ( self.Normal * math.random( 20,40*self.Scale) + VectorRand() * math.random( 25,50*self.Scale) )
+ Debris:SetLifeTime( 0 )
+ Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Scale/3 )
+ Debris:SetStartAlpha( 255 )
+ Debris:SetEndAlpha( 0 )
+ Debris:SetStartSize( 1*self.Scale )
+ Debris:SetEndSize( 1*self.Scale )
+ Debris:SetRoll( math.Rand(0, 360) )
+ Debris:SetRollDelta( math.Rand(-3, 3) )
+ Debris:SetAirResistance( 100 )
+ Debris:SetGravity( Vector( 0, 0, -650 ) )
+ Debris:SetColor( 120,120,120 )
+ end
+ end
+
+ for i=0, 5*self.Scale do
+
+ local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
+ if (Embers) then
+ Embers:SetVelocity ( (self.Normal - VectorRand()) * math.random(30*self.Scale,80*self.Scale) )
+ Embers:SetLifeTime( 0 )
+ Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Scale/5 )
+ Embers:SetStartAlpha( 255 )
+ Embers:SetEndAlpha( 0 )
+ Embers:SetStartSize( 2*self.Scale )
+ Embers:SetEndSize( 0*self.Scale )
+ Embers:SetStartLength( 5*self.Scale )
+ Embers:SetEndLength ( 0*self.Scale )
+ Embers:SetRoll( math.Rand(0, 360) )
+ Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Embers:SetAirResistance( 20 )
+ Embers:SetGravity( VectorRand()*10 )
+ Embers:SetColor( 200,200,200 )
+ end
+ end
+
+ local Sparks = EffectData()
+ Sparks:SetOrigin( self.Origin )
+ Sparks:SetNormal( self.Normal )
+ Sparks:SetMagnitude( self.Scale )
+ Sparks:SetScale( self.Scale )
+ Sparks:SetRadius( self.Scale )
+ util.Effect( "Sparks", Sparks )
+
+ end
+
+function EFFECT:Concrete()
+
+ util.Decal("GunShot1", self.Origin + self.DirVec*10, self.Origin - self.DirVec*10)
+
+ for i=0, 4*self.Scale do
+
+ local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
+ if (Debris) then
+ Debris:SetVelocity ( self.Normal * math.random( 20,40*self.Scale) + VectorRand() * math.random( 25,50*self.Scale) )
+ Debris:SetLifeTime( 0 )
+ Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Scale/3 )
+ Debris:SetStartAlpha( 255 )
+ Debris:SetEndAlpha( 0 )
+ Debris:SetStartSize( 1*self.Scale )
+ Debris:SetEndSize( 1*self.Scale )
+ Debris:SetRoll( math.Rand(0, 360) )
+ Debris:SetRollDelta( math.Rand(-3, 3) )
+ Debris:SetAirResistance( 100 )
+ Debris:SetGravity( Vector( 0, 0, -650 ) )
+ Debris:SetColor( 120,120,120 )
+ end
+ end
+
+ for i=0, 3*self.Scale do
+
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Smoke) then
+ Smoke:SetVelocity( self.Normal * math.random( 20,40*self.Scale) + VectorRand() * math.random( 25,50*self.Scale) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Scale/3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 1*self.Scale )
+ Smoke:SetEndSize( 2*self.Scale )
+ Smoke:SetRoll( math.Rand(150, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 200 )
+ Smoke:SetGravity( Vector( math.random(-5,5)*self.Scale, math.random(-5,5)*self.Scale, -50 ) )
+ Smoke:SetColor( 90,90,90 )
+ end
+
+ end
+
+ for i=0, 5*self.Scale do
+
+ local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
+ if (Embers) then
+ Embers:SetVelocity ( (self.Normal - VectorRand()) * math.random(30*self.Scale,80*self.Scale) )
+ Embers:SetLifeTime( 0 )
+ Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Scale/5 )
+ Embers:SetStartAlpha( 255 )
+ Embers:SetEndAlpha( 0 )
+ Embers:SetStartSize( 5*self.Scale )
+ Embers:SetEndSize( 0*self.Scale )
+ Embers:SetStartLength( 5*self.Scale )
+ Embers:SetEndLength ( 0*self.Scale )
+ Embers:SetRoll( math.Rand(0, 360) )
+ Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Embers:SetAirResistance( 20 )
+ Embers:SetGravity( VectorRand()*10 )
+ Embers:SetColor( 200,200,200 )
+ end
+ end
+
+ local Sparks = EffectData()
+ Sparks:SetOrigin( self.Origin )
+ Sparks:SetNormal( self.Normal )
+ Sparks:SetMagnitude( self.Scale )
+ Sparks:SetScale( self.Scale )
+ Sparks:SetRadius( self.Scale )
+ util.Effect( "Sparks", Sparks )
+
+ end
+
+/*---------------------------------------------------------
+ THINK
+---------------------------------------------------------*/
+function EFFECT:Think( )
+ return false
+end
+
+/*---------------------------------------------------------
+ Draw the effect
+---------------------------------------------------------*/
+function EFFECT:Render()
+end
+
+
\ No newline at end of file
diff --git a/lua/effects/acf_ap_ricochet/init.lua b/lua/effects/acf_ap_ricochet/init.lua
new file mode 100644
index 000000000..3299bf9fa
--- /dev/null
+++ b/lua/effects/acf_ap_ricochet/init.lua
@@ -0,0 +1,48 @@
+
+
+ /*---------------------------------------------------------
+ Initializes the effect. The data is a table of data
+ which was passed from the server.
+ ---------------------------------------------------------*/
+ function EFFECT:Init( data )
+
+ self.Origin = data:GetOrigin()
+ self.DirVec = data:GetNormal()
+ self.Velocity = data:GetScale() --Velocity of the projectile in gmod units
+ self.Mass = data:GetMagnitude() --Mass of the projectile in kg
+ self.Emitter = ParticleEmitter( self.Origin )
+
+ self.Scale = math.max(self.Mass * (self.Velocity/39.37)/100,1)^0.3
+
+ --self.Entity:EmitSound( "ambient/explosions/explode_1.wav" , 100 + self.Radius*10, 200 - self.Radius*10 )
+
+ local BulletEffect = {}
+ BulletEffect.Num = 1
+ BulletEffect.Src = self.Origin - self.DirVec
+ BulletEffect.Dir = self.DirVec
+ BulletEffect.Spread = Vector(0,0,0)
+ BulletEffect.Tracer = 0
+ BulletEffect.Force = 0
+ BulletEffect.Damage = 0
+ LocalPlayer():FireBullets(BulletEffect)
+
+ sound.Play( "/acf_other/ricochets/0000032"..math.random(0,2)..".wav", self.Origin, math.Clamp(self.Mass*200,65,500), math.Clamp(self.Velocity*0.01,25,255), 1 )
+
+ util.Decal("ExplosiveGunshot", self.Origin + self.DirVec*10, self.Origin - self.DirVec*10)
+
+ end
+
+/*---------------------------------------------------------
+ THINK
+---------------------------------------------------------*/
+function EFFECT:Think( )
+ return false
+end
+
+/*---------------------------------------------------------
+ Draw the effect
+---------------------------------------------------------*/
+function EFFECT:Render()
+end
+
+
\ No newline at end of file
diff --git a/lua/effects/acf_bulleteffect/init.lua b/lua/effects/acf_bulleteffect/init.lua
new file mode 100644
index 000000000..02be78755
--- /dev/null
+++ b/lua/effects/acf_bulleteffect/init.lua
@@ -0,0 +1,209 @@
+
+function EFFECT:Init( data )
+
+ self.Index = data:GetAttachment()
+ self:SetModel("models/munitions/round_100mm_shot.mdl")
+ if not ( self.Index ) then
+ --self:Remove()
+ self.Alive = false
+ return
+ end
+ self.CreateTime = ACF.CurTime
+
+ local Hit = data:GetScale()
+ local Bullet = ACF.BulletEffect[self.Index]
+
+ if (Hit > 0 and Bullet) then --Scale encodes the hit type, so if it's 0 it's a new bullet, else it's an update so we need to remove the effect
+
+ --print("Updating Bullet Effect")
+ Bullet.SimFlight = data:GetStart()*10 --Updating old effect with new values
+ Bullet.SimPos = data:GetOrigin()
+
+ if (Hit == 1) then --Bullet has reached end of flight, remove old effect
+
+ self.HitEnd = ACF.RoundTypes[Bullet.AmmoType]["endeffect"]
+ self:HitEnd( Bullet )
+ ACF.BulletEffect[self.Index] = nil --This is crucial, to effectively remove the bullet flight model from the client
+
+ elseif (Hit == 2) then --Bullet penetrated, don't remove old effect
+
+ self.HitPierce = ACF.RoundTypes[Bullet.AmmoType]["pierceeffect"]
+ self:HitPierce( Bullet )
+
+ elseif (Hit == 3) then --Bullet ricocheted, don't remove old effect
+
+ self.HitRicochet = ACF.RoundTypes[Bullet.AmmoType]["ricocheteffect"]
+ self:HitRicochet( Bullet )
+
+ end
+ ACF_SimBulletFlight( Bullet, self.Index )
+ --self:Remove() --This effect updated the old one, so it removes itself now
+ if IsValid(Bullet.Tracer) then Bullet.Tracer:Finish() end
+ self.Alive = false
+
+ else
+ --print("Creating Bullet Effect")
+ local BulletData = {}
+ BulletData.Crate = data:GetEntity()
+ --TODO: Check if it is actually a crate
+ if not IsValid(BulletData.Crate) then
+ --self:Remove()
+ self.Alive = false
+ return
+ end
+ BulletData.SimFlight = data:GetStart()*10
+ BulletData.SimPos = data:GetOrigin()
+ BulletData.SimPosLast = BulletData.SimPos
+ BulletData.Caliber = BulletData.Crate:GetNWFloat( "Caliber", 10 )
+ BulletData.RoundMass = BulletData.Crate:GetNWFloat( "ProjMass", 10 )
+ BulletData.FillerMass = BulletData.Crate:GetNWFloat( "FillerMass" )
+ BulletData.WPMass = BulletData.Crate:GetNWFloat( "WPMass" )
+ BulletData.DragCoef = BulletData.Crate:GetNWFloat( "DragCoef", 1 )
+ BulletData.AmmoType = BulletData.Crate:GetNWString( "AmmoType", "AP" )
+
+ if BulletData.Crate:GetNWFloat( "Tracer" ) > 0 then
+ BulletData.Tracer = ParticleEmitter( BulletData.SimPos )
+ BulletData.TracerColour = BulletData.Crate:GetNWVector( "TracerColour", BulletData.Crate:GetColor() ) or Vector(255,255,255)
+ end
+
+
+ BulletData.Accel = BulletData.Crate:GetNWVector( "Accel", Vector(0,0,-600))
+
+ BulletData.LastThink = CurTime() --ACF.CurTime
+ BulletData.Effect = self.Entity
+
+ ACF.BulletEffect[self.Index] = BulletData --Add all that data to the bullet table, overwriting if needed
+
+ self:SetPos( BulletData.SimPos ) --Moving the effect to the calculated position
+ self:SetAngles( BulletData.SimFlight:Angle() )
+ self.Alive = true
+
+ ACF_SimBulletFlight( ACF.BulletEffect[self.Index], self.Index )
+
+ end
+
+end
+
+function EFFECT:HitEnd()
+ --You overwrite this with your own function, defined in the ammo definition file
+ ACF.BulletEffect[self.Index] = nil --Failsafe
+end
+
+function EFFECT:HitPierce()
+ --You overwrite this with your own function, defined in the ammo definition file
+ ACF.BulletEffect[self.Index] = nil --Failsafe
+end
+
+function EFFECT:HitRicochet()
+ --You overwrite this with your own function, defined in the ammo definition file
+ ACF.BulletEffect[self.Index] = nil --Failsafe
+end
+
+function EFFECT:Think()
+
+ local Bullet = ACF.BulletEffect[self.Index]
+
+ if self.Alive and Bullet and self.CreateTime > ACF.CurTime-30 then
+ return true
+ end
+
+ --self:Remove()
+ if Bullet and IsValid(Bullet.Tracer) then Bullet.Tracer:Finish() end
+ return false
+
+end
+
+function EFFECT:ApplyMovement( Bullet )
+
+ local setPos = Bullet.SimPos
+ if((math.abs(setPos.x) > 16380) or (math.abs(setPos.y) > 16380) or (setPos.z < -16380)) then
+ --self:Remove()
+ if Bullet and IsValid(Bullet.Tracer) then Bullet.Tracer:Finish() end
+ self.Alive = false
+ return
+ end
+ if( setPos.z < 16380 ) then
+ self:SetPos( setPos )--Moving the effect to the calculated position
+ self:SetAngles( Bullet.SimFlight:Angle() )
+ end
+
+ if Bullet.Tracer and IsValid(Bullet.Tracer) then
+ local DeltaTime = ACF.CurTime - Bullet.LastThink
+ --local DeltaPos = Bullet.SimFlight*DeltaTime
+ local DeltaPos = Bullet.SimPos - Bullet.SimPosLast
+ local Length = math.max(DeltaPos:Length()*2,1)
+ local MaxSprites = 2 --math.min(math.floor(math.max(Bullet.Caliber/5,1)*1.333)+1,5)
+ local Light = Bullet.Tracer:Add( "sprites/acf_tracer.vmt", setPos)-- - DeltaPos )
+ if (Light) then
+ Light:SetAngles( Bullet.SimFlight:Angle() )
+ Light:SetVelocity( Bullet.SimFlight:GetNormalized() ) --Vector() ) --Bullet.SimFlight )
+ Light:SetColor( Bullet.TracerColour.x, Bullet.TracerColour.y, Bullet.TracerColour.z )
+ Light:SetDieTime( math.Clamp(ACF.CurTime-self.CreateTime,0.075,0.15) ) -- 0.075, 0.1
+ Light:SetStartAlpha( 255 )
+ Light:SetEndAlpha( 155 )
+ Light:SetStartSize( 15*Bullet.Caliber ) -- 5
+ Light:SetEndSize( 1 ) --15*Bullet.Caliber
+ Light:SetStartLength( Length )
+ Light:SetEndLength( 1 ) --Length
+ end
+ for i=1, MaxSprites do
+ local Smoke = Bullet.Tracer:Add( "particle/smokesprites_000"..math.random(1,9), setPos - (DeltaPos*i/MaxSprites) )
+ if (Smoke) then
+ Smoke:SetAngles( Bullet.SimFlight:Angle() )
+ Smoke:SetVelocity( Bullet.SimFlight*0.05 )
+ Smoke:SetColor( 200 , 200 , 200 )
+ Smoke:SetDieTime( 0.6 ) -- 1.2
+ Smoke:SetStartAlpha( 10 )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 1 )
+ Smoke:SetEndSize( Length/400*Bullet.Caliber )
+ Smoke:SetRollDelta( 0.1 )
+ Smoke:SetAirResistance( 150 )
+ Smoke:SetGravity( Vector(0,0,20) )
+ --Smoke:SetCollide( 0 )
+ --Smoke:SetLighting( 0 )
+ end
+ end
+ end
+end
+
+--[[
+function EFFECT:HitEffect( HitPos, Energy, EffectType ) --EffectType key : 1 = Round stopped, 2 = Round penetration
+
+ if (EffectType > 0) then
+ local BulletEffect = {}
+ BulletEffect.Num = 1
+ BulletEffect.Src = HitPos - self.SimFlight:GetNormalized()*20
+ BulletEffect.Dir = self.SimFlight
+ BulletEffect.Spread = Vector(0,0,0)
+ BulletEffect.Tracer = 0
+ BulletEffect.Force = 0
+ BulletEffect.Damage = 0
+ self.Entity:FireBullets(BulletEffect)
+ end
+ if (EffectType == 2) then
+ local Spall = EffectData()
+ Spall:SetOrigin( HitPos )
+ Spall:SetNormal( (self.SimFlight):GetNormalized() )
+ Spall:SetScale( math.max(Energy/5000,1) )
+ util.Effect( "AP_Hit", Spall )
+ elseif (EffectType == 3) then
+ local Sparks = EffectData()
+ Sparks:SetOrigin( HitPos )
+ Sparks:SetNormal( (self.SimFlight):GetNormalized() )
+ util.Effect( "ManhackSparks", Sparks )
+ end
+
+end
+--]]
+
+function EFFECT:Render()
+
+ local Bullet = ACF.BulletEffect[self.Index]
+
+ if (Bullet) then
+ self.Entity:SetModelScale( Bullet.Caliber/10 , 0 )
+ self.Entity:DrawModel() // Draw the model.
+ end
+
+end
diff --git a/lua/effects/ACF_Cookoff/init.lua b/lua/effects/acf_cookoff/init.lua
similarity index 100%
rename from lua/effects/ACF_Cookoff/init.lua
rename to lua/effects/acf_cookoff/init.lua
diff --git a/lua/effects/acf_heat_explosion/init.lua b/lua/effects/acf_heat_explosion/init.lua
new file mode 100644
index 000000000..54ddbe5b7
--- /dev/null
+++ b/lua/effects/acf_heat_explosion/init.lua
@@ -0,0 +1,96 @@
+
+
+ /*---------------------------------------------------------
+ Initializes the effect. The data is a table of data
+ which was passed from the server.
+ ---------------------------------------------------------*/
+function EFFECT:Init( data )
+
+ self.Origin = data:GetOrigin()
+ self.DirVec = data:GetNormal()
+ self.Radius = math.max(data:GetRadius()/50,1)
+ self.Emitter = ParticleEmitter( self.Origin )
+ self.ParticleMul = tonumber(LocalPlayer():GetInfo("acf_cl_particlemul")) or 1
+
+ for i=0, 3*self.Radius*self.ParticleMul do
+
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Smoke) then
+ Smoke:SetVelocity( (-self.DirVec + VectorRand()/10) * math.random(50,130*self.Radius) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 2*self.Radius )
+ Smoke:SetEndSize( 15*self.Radius )
+ Smoke:SetRoll( math.Rand(150, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 300 )
+ Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -450 ) )
+ Smoke:SetColor( 160,160,160)
+ end
+
+ end
+
+ for i=0, 4*self.Radius*self.ParticleMul do
+
+ local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
+ if (Debris) then
+ Debris:SetVelocity ( (self.DirVec + VectorRand()/10) * math.random(250*self.Radius,450*self.Radius) )
+ Debris:SetLifeTime( 0 )
+ Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Radius/3 )
+ Debris:SetStartAlpha( 255 )
+ Debris:SetEndAlpha( 0 )
+ Debris:SetStartSize( 0.3*self.Radius )
+ Debris:SetEndSize( 0.3*self.Radius )
+ Debris:SetRoll( math.Rand(0, 360) )
+ Debris:SetRollDelta( math.Rand(-3, 3) )
+ Debris:SetAirResistance( 200 )
+ Debris:SetGravity( Vector( 0, 0, -650 ) )
+ Debris:SetColor( 120,120,120 )
+ end
+ end
+
+ for i=0, 5*self.Radius*self.ParticleMul do
+
+ local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
+ if (Embers) then
+ Embers:SetVelocity ( (self.DirVec + VectorRand()/10) * math.random(50*self.Radius,300*self.Radius) )
+ Embers:SetLifeTime( 0 )
+ Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Radius/3 )
+ Embers:SetStartAlpha( 255 )
+ Embers:SetEndAlpha( 0 )
+ Embers:SetStartSize( 1*self.Radius )
+ Embers:SetEndSize( 0*self.Radius )
+ Embers:SetStartLength( 5*self.Radius )
+ Embers:SetEndLength ( 0*self.Radius )
+ Embers:SetRoll( math.Rand(0, 360) )
+ Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Embers:SetAirResistance( 20 )
+ Embers:SetGravity( Vector( 0, 0, -650 ) )
+ Embers:SetColor( 200,200,200 )
+ end
+ end
+
+ local Flash = EffectData()
+ Flash:SetOrigin( self.Origin )
+ Flash:SetScale( self.Radius )
+ Flash:SetNormal( self.DirVec )
+ util.Effect( "ACF_Scaled_Explosion", Flash )
+
+ end
+
+/*---------------------------------------------------------
+ THINK
+---------------------------------------------------------*/
+function EFFECT:Think( )
+
+end
+
+/*---------------------------------------------------------
+ Draw the effect
+---------------------------------------------------------*/
+function EFFECT:Render()
+end
+
+
diff --git a/lua/effects/acf_muzzleflash/init.lua b/lua/effects/acf_muzzleflash/init.lua
new file mode 100644
index 000000000..9a835c5b9
--- /dev/null
+++ b/lua/effects/acf_muzzleflash/init.lua
@@ -0,0 +1,70 @@
+
+
+ /*---------------------------------------------------------
+ Initializes the effect. The data is a table of data
+ which was passed from the server.
+ ---------------------------------------------------------*/
+ function EFFECT:Init( data )
+
+ local Gun = data:GetEntity()
+ if not IsValid(Gun) then return end
+
+ local Sound = Gun:GetNWString( "Sound" )
+ --local RoundType = ACF.IdRounds[data:GetSurfaceProp()]
+ local Propellant = data:GetScale()
+ local ReloadTime = data:GetMagnitude()
+
+ local Class = Gun:GetNWString( "Class" )
+ local ClassData = list.Get("ACFClasses").GunClass[Class]
+
+ local Attachment = "muzzle"
+ local longbarrel = ClassData.longbarrel
+ if longbarrel ~= nil then
+ if Gun:GetBodygroup( longbarrel.index ) == longbarrel.submodel then
+ Attachment = longbarrel.newpos
+ end
+ end
+
+ local nosound = (Sound == "")
+ if( CLIENT and not IsValidSound( Sound ) ) then
+ Sound = ClassData["sound"]
+ end
+
+ if Gun:IsValid() then
+ if Propellant > 0 then
+ if not nosound then
+ local SoundPressure = (Propellant*1000)^0.5
+ sound.Play( Sound, Gun:GetPos() , math.Clamp(SoundPressure,75,127), 100) --wiki documents level tops out at 180, but seems to fall off past 127
+ if not ((Class == "MG") or (Class == "RAC")) then
+ sound.Play( Sound, Gun:GetPos() , math.Clamp(SoundPressure,75,127), 100)
+ if (SoundPressure > 127) then
+ sound.Play( Sound, Gun:GetPos() , math.Clamp(SoundPressure-127,1,127), 100)
+ end
+ end
+ --sound.Play( ACF.Classes["GunClass"][Class]["soundDistance"], Gun:GetPos() , math.Clamp(SoundPressure,75,255), math.Clamp(100,15,255))
+ --sound.Play( ACF.Classes["GunClass"][Class]["soundNormal"], Gun:GetPos() , math.Clamp(SoundPressure,75,255), math.Clamp(100,15,255))
+ end
+
+ local Muzzle = Gun:GetAttachment( Gun:LookupAttachment(Attachment)) or { Pos = Gun:GetPos(), Ang = Gun:GetAngles() }
+ ParticleEffect( ClassData["muzzleflash"], Muzzle.Pos, Muzzle.Ang, Gun )
+ Gun:Animate( Class, ReloadTime, false )
+ else
+ Gun:Animate( Class, ReloadTime, true )
+ end
+ end
+
+ end
+
+
+/*---------------------------------------------------------
+ THINK
+---------------------------------------------------------*/
+function EFFECT:Think( )
+ return false
+end
+
+/*---------------------------------------------------------
+ Draw the effect
+---------------------------------------------------------*/
+function EFFECT:Render()
+end
diff --git a/lua/effects/acf_scaled_explosion/init.lua b/lua/effects/acf_scaled_explosion/init.lua
new file mode 100644
index 000000000..0e1dbdd34
--- /dev/null
+++ b/lua/effects/acf_scaled_explosion/init.lua
@@ -0,0 +1,357 @@
+
+
+ /*---------------------------------------------------------
+ Initializes the effect. The data is a table of data
+ which was passed from the server.
+ ---------------------------------------------------------*/
+function EFFECT:Init( data )
+
+ self.Origin = data:GetOrigin()
+ self.DirVec = data:GetNormal()
+ self.Radius = math.max(data:GetRadius()/50,1)
+ self.Emitter = ParticleEmitter( self.Origin )
+ self.ParticleMul = tonumber(LocalPlayer():GetInfo("acf_cl_particlemul")) or 1
+
+ local ImpactTr = { }
+ ImpactTr.start = self.Origin - self.DirVec*20
+ ImpactTr.endpos = self.Origin + self.DirVec*20
+ local Impact = util.TraceLine(ImpactTr) --Trace to see if it will hit anything
+ self.Normal = Impact.HitNormal
+
+ local GroundTr = { }
+ GroundTr.start = self.Origin + Vector(0,0,1)
+ GroundTr.endpos = self.Origin - Vector(0,0,1)*self.Radius*20
+ GroundTr.mask = 131083
+ local Ground = util.TraceLine(GroundTr)
+
+ -- Material Enum
+ -- 65 ANTLION
+ -- 66 BLOODYFLESH
+ -- 67 CONCRETE / NODRAW
+ -- 68 DIRT
+ -- 70 FLESH
+ -- 71 GRATE
+ -- 72 ALIENFLESH
+ -- 73 CLIP
+ -- 76 PLASTIC
+ -- 77 METAL
+ -- 78 SAND
+ -- 79 FOLIAGE
+ -- 80 COMPUTER
+ -- 83 SLOSH
+ -- 84 TILE
+ -- 86 VENT
+ -- 87 WOOD
+ -- 89 GLASS
+
+ local Mat = Impact.MatType
+ local SmokeColor = Vector(90,90,90)
+ if Impact.HitSky or not Impact.Hit then
+ SmokeColor = Vector(90,90,90)
+ self:Airburst( SmokeColor )
+ elseif Mat == 71 or Mat == 73 or Mat == 77 or Mat == 80 then -- Metal
+ SmokeColor = Vector(170,170,170)
+ self:Metal( SmokeColor )
+ elseif Mat == 68 or Mat == 79 then -- Dirt
+ SmokeColor = Vector(100,80,50)
+ self:Dirt( SmokeColor )
+ elseif Mat == 78 then -- Sand
+ SmokeColor = Vector(100,80,50)
+ self:Sand( SmokeColor )
+ else -- Nonspecific
+ SmokeColor = Vector(90,90,90)
+ self:Concrete( SmokeColor )
+ end
+
+ if Ground.HitWorld then
+ self:Shockwave( Ground, SmokeColor )
+ end
+
+ end
+
+function EFFECT:Core()
+
+ for i=0, 2*self.Radius*self.ParticleMul do
+
+ local Flame = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin)
+ if (Flame) then
+ Flame:SetVelocity( VectorRand() * math.random(50,150*self.Radius) )
+ Flame:SetLifeTime( 0 )
+ Flame:SetDieTime( 0.15 )
+ Flame:SetStartAlpha( math.Rand( 50, 255 ) )
+ Flame:SetEndAlpha( 0 )
+ Flame:SetStartSize( 2.5*self.Radius )
+ Flame:SetEndSize( 15*self.Radius )
+ Flame:SetRoll( math.random(120, 360) )
+ Flame:SetRollDelta( math.Rand(-1, 1) )
+ Flame:SetAirResistance( 300 )
+ Flame:SetGravity( Vector( 0, 0, 4 ) )
+ Flame:SetColor( 255,255,255 )
+ end
+
+ end
+
+ for i=0, 4*self.Radius*self.ParticleMul do
+
+ local Debris = self.Emitter:Add( "effects/fleck_tile"..math.random(1,2), self.Origin )
+ if (Debris) then
+ Debris:SetVelocity ( VectorRand() * math.random(150*self.Radius,250*self.Radius) )
+ Debris:SetLifeTime( 0 )
+ Debris:SetDieTime( math.Rand( 1.5 , 3 )*self.Radius/3 )
+ Debris:SetStartAlpha( 255 )
+ Debris:SetEndAlpha( 0 )
+ Debris:SetStartSize( 1*self.Radius )
+ Debris:SetEndSize( 1*self.Radius )
+ Debris:SetRoll( math.Rand(0, 360) )
+ Debris:SetRollDelta( math.Rand(-3, 3) )
+ Debris:SetAirResistance( 10 )
+ Debris:SetGravity( Vector( 0, 0, -650 ) )
+ Debris:SetColor( 120,120,120 )
+ end
+ end
+
+ for i=0, 5*self.Radius*self.ParticleMul do
+
+ local Embers = self.Emitter:Add( "particles/flamelet"..math.random(1,5), self.Origin )
+ if (Embers) then
+ Embers:SetVelocity ( VectorRand() * math.random(70*self.Radius,160*self.Radius) )
+ Embers:SetLifeTime( 0 )
+ Embers:SetDieTime( math.Rand( 0.3 , 1 )*self.Radius/3 )
+ Embers:SetStartAlpha( 255 )
+ Embers:SetEndAlpha( 0 )
+ Embers:SetStartSize( 1*self.Radius )
+ Embers:SetEndSize( 0*self.Radius )
+ Embers:SetStartLength( 5*self.Radius )
+ Embers:SetEndLength ( 0*self.Radius )
+ Embers:SetRoll( math.Rand(0, 360) )
+ Embers:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Embers:SetAirResistance( 20 )
+ Embers:SetGravity( Vector( 0, 0, -650 ) )
+ Embers:SetColor( 200,200,200 )
+ end
+ end
+
+ for i=0, 2*self.Radius*self.ParticleMul do
+ local Whisp = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Whisp) then
+ Whisp:SetVelocity(VectorRand() * math.random( 150,250*self.Radius) )
+ Whisp:SetLifeTime( 0 )
+ Whisp:SetDieTime( math.Rand( 3 , 5 )*self.Radius/3 )
+ Whisp:SetStartAlpha( math.Rand( 20, 50 ) )
+ Whisp:SetEndAlpha( 0 )
+ Whisp:SetStartSize( 10*self.Radius )
+ Whisp:SetEndSize( 80*self.Radius )
+ Whisp:SetRoll( math.Rand(150, 360) )
+ Whisp:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Whisp:SetAirResistance( 100 )
+ Whisp:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, 0 ) )
+ Whisp:SetColor( 150,150,150 )
+ end
+ end
+
+ if self.Radius*self.ParticleMul > 4 then
+ for i=0, 0.5*self.Radius*self.ParticleMul do
+ local Cookoff = EffectData()
+ Cookoff:SetOrigin( self.Origin )
+ Cookoff:SetScale( self.Radius/6 )
+ util.Effect( "ACF_Cookoff", Cookoff )
+ end
+ end
+ sound.Play( "ambient/explosions/explode_5.wav", self.Origin , math.Clamp(self.Radius*10,75,165), math.Clamp(300 - self.Radius*12,15,255))
+ sound.Play( "ambient/explosions/explode_4.wav", self.Origin , math.Clamp(self.Radius*10,75,165), math.Clamp(300 - self.Radius*25,15,255))
+
+end
+
+function EFFECT:Shockwave( Ground, SmokeColor )
+
+ local Mat = Ground.MatType
+ local Radius = (1-Ground.Fraction)*self.Radius
+ local Density = 15*Radius
+ local Angle = Ground.HitNormal:Angle()
+ for i=0, Density*self.ParticleMul do
+
+ Angle:RotateAroundAxis(Angle:Forward(), (360/Density))
+ local ShootVector = Angle:Up()
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), Ground.HitPos )
+ if (Smoke) then
+ Smoke:SetVelocity( ShootVector * math.Rand(5,200*Radius) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*Radius /3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 120 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 4*Radius )
+ Smoke:SetEndSize( 15*Radius )
+ Smoke:SetRoll( math.Rand(0, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 200 )
+ Smoke:SetGravity( Vector( math.Rand( -20 , 20 ), math.Rand( -20 , 20 ), math.Rand( 10 , 100 ) ) )
+ Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+
+ end
+
+end
+
+function EFFECT:Metal( SmokeColor )
+
+ self:Core()
+
+ for i=0, 3*self.Radius*self.ParticleMul do
+
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Smoke) then
+ Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 5*self.Radius )
+ Smoke:SetEndSize( 30*self.Radius )
+ Smoke:SetRoll( math.Rand(150, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 100 )
+ Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
+ Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+
+ end
+
+end
+
+function EFFECT:Concrete( SmokeColor )
+
+ self:Core()
+
+ for i=0, 3*self.Radius*self.ParticleMul do
+
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Smoke) then
+ Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 5*self.Radius )
+ Smoke:SetEndSize( 30*self.Radius )
+ Smoke:SetRoll( math.Rand(150, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 100 )
+ Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
+ Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+
+ end
+
+end
+
+function EFFECT:Dirt( SmokeColor )
+
+ self:Core()
+
+ for i=0, 3*self.Radius*self.ParticleMul do
+
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Smoke) then
+ Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 5*self.Radius )
+ Smoke:SetEndSize( 30*self.Radius )
+ Smoke:SetRoll( math.Rand(150, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 100 )
+ Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
+ Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+
+ end
+
+end
+
+function EFFECT:Sand( SmokeColor )
+
+ self:Core()
+
+ for i=0, 3*self.Radius*self.ParticleMul do
+
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Smoke) then
+ Smoke:SetVelocity( self.Normal * math.random( 50,80*self.Radius) + VectorRand() * math.random( 30,60*self.Radius) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 5*self.Radius )
+ Smoke:SetEndSize( 30*self.Radius )
+ Smoke:SetRoll( math.Rand(150, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 100 )
+ Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
+ Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+
+ end
+
+end
+
+function EFFECT:Airburst( SmokeColor )
+
+ self:Core()
+
+ for i=0, 3*self.Radius*self.ParticleMul do
+
+ local Smoke = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (Smoke) then
+ Smoke:SetVelocity( VectorRand() * math.random( 25,50*self.Radius) )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
+ Smoke:SetStartAlpha( math.Rand( 50, 150 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( 5*self.Radius )
+ Smoke:SetEndSize( 30*self.Radius )
+ Smoke:SetRoll( math.Rand(150, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 100 )
+ Smoke:SetGravity( Vector( math.random(-5,5)*self.Radius, math.random(-5,5)*self.Radius, -50 ) )
+ Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+
+ end
+
+ for i=0, 10*self.Radius*self.ParticleMul do
+
+ local AirBurst = self.Emitter:Add( "particle/smokesprites_000"..math.random(1,9), self.Origin )
+ if (AirBurst) then
+ AirBurst:SetVelocity( VectorRand() * math.random( 150,200*self.Radius) )
+ AirBurst:SetLifeTime( 0 )
+ AirBurst:SetDieTime( math.Rand( 1 , 2 )*self.Radius/3 )
+ AirBurst:SetStartAlpha( math.Rand( 100, 255 ) )
+ AirBurst:SetEndAlpha( 0 )
+ AirBurst:SetStartSize( 6*self.Radius )
+ AirBurst:SetEndSize( 35*self.Radius )
+ AirBurst:SetRoll( math.Rand(150, 360) )
+ AirBurst:SetRollDelta( math.Rand(-0.2, 0.2) )
+ AirBurst:SetAirResistance( 200 )
+ AirBurst:SetGravity( Vector( math.random(-10,10)*self.Radius, math.random(-10,10)*self.Radius, 20 ) )
+ AirBurst:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+ end
+
+end
+
+/*---------------------------------------------------------
+ THINK
+---------------------------------------------------------*/
+function EFFECT:Think( )
+
+end
+
+/*---------------------------------------------------------
+ Draw the effect
+---------------------------------------------------------*/
+function EFFECT:Render()
+end
+
+
diff --git a/lua/effects/acf_smoke/init.lua b/lua/effects/acf_smoke/init.lua
new file mode 100644
index 000000000..215c16488
--- /dev/null
+++ b/lua/effects/acf_smoke/init.lua
@@ -0,0 +1,92 @@
+
+ /*---------------------------------------------------------
+ Initializes the effect. The data is a table of data
+ which was passed from the server.
+ ---------------------------------------------------------*/
+
+function EFFECT:Init( data )
+ self.Origin = data:GetOrigin()
+ self.DirVec = data:GetNormal()
+ self.Colour = data:GetStart()
+ self.Radius = math.min(math.log(1+data:GetRadius())/0.02303,350) --smoke filler (long lasting, slow deploy)
+ self.Magnitude = math.min(math.log(1+data:GetMagnitude())/0.02303,350) --WP filler (fast deploy, short duration)
+ --print(self.Radius.." "..self.Magnitude)
+ self.Emitter = ParticleEmitter( self.Origin )
+
+ local ImpactTr = { }
+ ImpactTr.start = self.Origin - self.DirVec*20
+ ImpactTr.endpos = self.Origin + self.DirVec*20
+ local Impact = util.TraceLine(ImpactTr) --Trace to see if it will hit anything
+ self.Normal = Impact.HitNormal
+
+ local GroundTr = { }
+ GroundTr.start = self.Origin + Vector(0,0,1)
+ GroundTr.endpos = self.Origin - Vector(0,0,1)*self.Radius
+ GroundTr.mask = 131083
+ local Ground = util.TraceLine(GroundTr)
+
+ local SmokeColor = self.Colour or Vector(255,255,255)
+ if not Ground.HitWorld then Ground.HitNormal = Vector(0,0,1) end
+
+ --if adjusting, update display data / crate text in smoke round
+ if self.Magnitude > 0 then
+ self:SmokeFiller( Ground, SmokeColor, self.Magnitude*1.25, 1.0, 6+self.Magnitude/10 ) --quick build and dissipate
+ end
+
+ if self.Radius > 0 then
+ self:SmokeFiller( Ground, SmokeColor, self.Radius*1.25, 0.15, 20+self.Radius/4 ) --slow build but long lasting
+ end
+
+ self.Emitter:Finish()
+end
+
+local smokes = {
+ "particle/smokesprites_0001",
+ "particle/smokesprites_0002",
+ "particle/smokesprites_0003",
+ "particle/smokesprites_0004",
+ "particle/smokesprites_0005",
+ "particle/smokesprites_0006",
+ "particle/smokesprites_0008"
+}
+
+local function smokePuff(self, Ground, ShootVector, Radius, RadiusMod, Density, i, wind, SmokeColor, DeploySpeed, Lifetime)
+ local Smoke = self.Emitter:Add( smokes[math.random(1, #smokes)], Ground.HitPos )
+ if (Smoke) then
+ Smoke:SetVelocity( (ShootVector + Vector(0, 0, 0.2)) * (Radius * RadiusMod) * DeploySpeed )
+ Smoke:SetLifeTime( 0 )
+ Smoke:SetDieTime( math.Clamp(Lifetime, 1, 60) )
+ Smoke:SetStartAlpha( math.Rand( 200, 255 ) )
+ Smoke:SetEndAlpha( 0 )
+ Smoke:SetStartSize( math.Clamp((Radius * RadiusMod) * DeploySpeed, 5, 1000) )
+ Smoke:SetEndSize( math.Clamp(Radius * RadiusMod * 4, 150, 4000) )
+ Smoke:SetRoll( math.Rand(0, 360) )
+ Smoke:SetRollDelta( math.Rand(-0.2, 0.2) )
+ Smoke:SetAirResistance( 100 * DeploySpeed )
+ Smoke:SetGravity( Vector( math.Rand( -10 , 10 ) + wind * 0.5 + (wind * i/Density), math.Rand( -10 , 10 ), math.Rand( 5 , 15 ) ) * DeploySpeed )
+ Smoke:SetColor( SmokeColor.x,SmokeColor.y,SmokeColor.z )
+ end
+end
+
+
+function EFFECT:SmokeFiller( Ground, SmokeColor, Radius, DeploySpeed, Lifetime )
+
+ local Density = Radius/18
+ local Angle = Ground.HitNormal:Angle()
+ local wind = ACF.SmokeWind or 0
+ local ShootVector = Ground.HitNormal * 0.5
+ --print(Radius..", "..Density)
+
+ smokePuff(self, Ground, Vector(0, 0, 0.3), Radius, 1.5, Density, 0, wind, SmokeColor, DeploySpeed, Lifetime) --smoke filler initial upward puff
+ for i=0, math.floor(Density) do
+ smokePuff(self, Ground, ShootVector, Radius, 1, Density, i, wind, SmokeColor, DeploySpeed, Lifetime)
+
+ ShootVector = Angle and Angle:Up()
+ Angle:RotateAroundAxis(Angle:Forward(), (360/Density))
+ end
+end
+
+--keep this here, error pops up if it's removed
+function EFFECT:Render()
+end
+
diff --git a/lua/effects/ACF_Tracer/init.lua b/lua/effects/acf_tracer/init.lua
similarity index 100%
rename from lua/effects/ACF_Tracer/init.lua
rename to lua/effects/acf_tracer/init.lua
diff --git a/lua/effects/Shaped_Charge/init.lua b/lua/effects/shaped_charge/init.lua
similarity index 100%
rename from lua/effects/Shaped_Charge/init.lua
rename to lua/effects/shaped_charge/init.lua
diff --git a/lua/entities/ACF_Ammo/cl_init.lua b/lua/entities/ACF_Ammo/cl_init.lua
deleted file mode 100644
index a277b050b..000000000
--- a/lua/entities/ACF_Ammo/cl_init.lua
+++ /dev/null
@@ -1,37 +0,0 @@
-include("shared.lua")
-
-ENT.RenderGroup = RENDERGROUP_OPAQUE
-
-function ENT:Draw()
- self:DoNormalDraw()
- Wire_Render(self.Entity)
-end
-
-function ENT:DoNormalDraw()
- local e = self.Entity
- if (LocalPlayer():GetEyeTrace().Entity == e and EyePos():Distance(e:GetPos()) < 256) then
- local Tracer = ""
- if self:GetNetworkedInt("Tracer") > 0 then Tracer = "-T" end
- local txt = self:GetNetworkedString("AmmoID").." : " ..self:GetNetworkedString("Ammo").. "\nRound Type : "..self:GetNetworkedString("AmmoType")..Tracer.."\n"
- self.AmmoString = ACF.RoundTypes[self:GetNetworkedString("AmmoType")]["cratetxt"]
- local Ammotxt = self:AmmoString()
- if (not game.SinglePlayer()) then
- local PlayerName = self:GetPlayerName()
- txt = txt .."".. Ammotxt .. "\n(" .. PlayerName .. ")"
- end
- AddWorldTip(e:EntIndex(),txt,0.5,e:GetPos(),e)
- end
- e:DrawModel()
-end
-
-function ENT:AmmoString()
-
- return ""
-end
-
-function ENT:Think()
- if (CurTime() >= (self.NextRBUpdate or 0)) then
- self.NextRBUpdate = CurTime() + math.random(30,100)/10 --update renderbounds every 3 to 10 seconds
- Wire_UpdateRenderBounds(self.Entity)
- end
-end
diff --git a/lua/entities/ACF_Ammo/init.lua b/lua/entities/ACF_Ammo/init.lua
deleted file mode 100644
index f3fd91a2b..000000000
--- a/lua/entities/ACF_Ammo/init.lua
+++ /dev/null
@@ -1,340 +0,0 @@
-AddCSLuaFile( "shared.lua" )
-AddCSLuaFile( "cl_init.lua" )
-
-include('shared.lua')
-
-function ENT:Initialize()
-
- self.SpecialHealth = true --If true needs a special ACF_Activate function
- self.SpecialDamage = true --If true needs a special ACF_OnDamage function
- self.IsExplosive = true
- self.Exploding = false
- self.Damaged = false
- self.CanUpdate = true
- self.Load = false
-
- self.Master = {}
- self.Sequence = 0
-
- self.WireDebugName = "Ammo Crate"
- self.Inputs = Wire_CreateInputs( self.Entity, { "Active"} )
- self.Outputs = Wire_CreateOutputs( self.Entity, { "Munitions" , "On Fire" } )
-
- self.NextThink = CurTime() + 1
-
-end
-
-function ENT:ACF_Activate( Recalc )
-
- local EmptyMass = math.max(self.EmptyMass, self:GetPhysicsObject():GetMass() - self:AmmoMass())
- local Size = self.OBBMaxs(self) - self.OBBMins(self)
- local Aera = ((Size.x * Size.y)+(Size.x * Size.z)+(Size.y * Size.z)) * 6.45 --Converting from square in to square cm, fuck imperial
- local Volume = Size.x * Size.y * Size.z * 16.38
- local Armour = EmptyMass*1000 / Aera / 0.78 --So we get the equivalent thickness of that prop in mm if all it's weight was a steel plate
- local Health = Volume/ACF.Threshold --Setting the threshold of the prop aera gone
- local Percent = 1
-
- if Recalc then
- Percent = self.ACF.Health/self.ACF.MaxHealth
- end
- self.ACF = {}
- self.ACF.Health = Health * Percent
- self.ACF.MaxHealth = Health
- self.ACF.Armour = Armour * (0.5 + Percent/2)
- self.ACF.MaxArmour = Armour
- self.ACF.Type = nil
- self.ACF.Mass = self.Mass
- self.ACF.Density = (self:GetPhysicsObject():GetMass()*1000)/Volume
- self.ACF.Type = "Prop"
-
-end
-
-function ENT:ACF_OnDamage( Entity , Energy , FrAera , Angle , Inflictor ) --This function needs to return HitRes
-
- local HitRes = ACF_PropDamage( Entity , Energy , FrAera , Angle , Inflictor ) --Calling the standard damage prop function
-
- if self.Exploding or not self.IsExplosive then return HitRes end
- if HitRes.Kill then
- self.Exploding = true
- if( Inflictor and Inflictor:IsValid() and Inflictor:IsPlayer() ) then
- self.Inflictor = Inflictor
- end
- if self.Ammo > 1 then
- ACF_AmmoExplosion( self.Entity , self.Entity:GetPos() )
- else
- ACF_HEKill( self.Entity , VectorRand() )
- end
- end
-
- if self.Damaged then return HitRes end
- local Ratio = (HitRes.Damage/self.BulletData["RoundVolume"])^0.2
- --print(Ratio)
- if ( Ratio * self.Capacity/self.Ammo ) > math.Rand(0,1) then
- self.Damaged = CurTime() + (5 - Ratio*3)
- Wire_TriggerOutput(self.Entity, "On Fire", 1)
- end
-
- return HitRes --This function needs to return HitRes
-end
-
-function MakeACF_Ammo(Owner, Pos, Angle, Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
-
- if not Owner:CheckLimit("_acf_ammo") then return false end
-
- local Ammo = ents.Create("ACF_Ammo")
- if not Ammo:IsValid() then return false end
- Ammo:SetAngles(Angle)
- Ammo:SetPos(Pos)
- Ammo:Spawn()
- Ammo:SetPlayer(Owner)
- Ammo.Owner = Owner
-
- Ammo.Model = ACF.Weapons["Ammo"][Id]["model"]
- Ammo:SetModel( Ammo.Model )
-
- Ammo:PhysicsInit( SOLID_VPHYSICS )
- Ammo:SetMoveType( MOVETYPE_VPHYSICS )
- Ammo:SetSolid( SOLID_VPHYSICS )
-
- Ammo.Id = Id
- Ammo:CreateAmmo(Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
-
- Ammo.Ammo = Ammo.Capacity
- Ammo.EmptyMass = ACF.Weapons["Ammo"][Ammo.Id]["weight"]
- Ammo.Mass = Ammo.EmptyMass + Ammo:AmmoMass()
-
- local phys = Ammo:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:SetMass( Ammo.Mass )
- end
-
- undo.Create("ACF Ammo")
- undo.AddEntity( Ammo )
- undo.SetPlayer( Owner )
- undo.Finish()
-
- Owner:AddCount( "_acf_ammo", Ammo )
- Owner:AddCleanup( "acfmenu", Ammo )
-
- return Ammo
-end
-list.Set( "ACFCvars", "acf_ammo" , {"id", "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9", "data10"} )
-duplicator.RegisterEntityClass("acf_ammo", MakeACF_Ammo, "Pos", "Angle", "Id", "RoundId", "RoundType", "RoundPropellant", "RoundProjectile", "RoundData5", "RoundData6", "RoundData7", "RoundData8", "RoundData9", "RoundData10" )
-
-function ENT:Update( ArgsTable ) --That table is the player data, as sorted in the ACFCvars above, with player who shot, and pos and angle of the tool trace inserted at the start
-
- local Feedback = "Ammocrate updated succesfully"
-
- if ( ArgsTable[1] != self.Owner ) then --Argtable[1] is the player that shot the tool
- Feedback = "You don't own that ammo crate !"
- return end
-
- if ( ArgsTable[6] == "Refill" ) then --Argtable[6] is the round type. If it's refill it shouldn't be loaded into guns, so we refuse to change to it
- Feedback = "Refill ammo type is only avaliable for new crates"
- return end
-
- if ( ArgsTable[5] != self.RoundId ) then --Argtable[5] is the weapon ID the new ammo loads into
- for Key, Gun in pairs( self.Master ) do
- if Gun:IsValid() then
- Gun:Unlink( self.Entity )
- end
- end
- Feedback = "New ammo type loaded, crate unlinked"
- end
-
- local AmmoPercent = self.Ammo/math.max(self.Capacity,1)
-
- self:CreateAmmo(ArgsTable[4], ArgsTable[5], ArgsTable[6], ArgsTable[7], ArgsTable[8], ArgsTable[9], ArgsTable[10], ArgsTable[11], ArgsTable[12], ArgsTable[13], ArgsTable[14])
-
- self.Ammo = math.floor(self.Capacity*AmmoPercent)
- local AmmoMass = self:AmmoMass()
- self.Mass = math.min(self.EmptyMass, self.Entity:GetPhysicsObject():GetMass() - AmmoMass) + AmmoMass*(self.Ammo/math.max(self.Capacity,1))
-
- return FeedBack
-end
-
-function ENT:CreateAmmo(Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
-
- --Data 1 to 4 are should always be Round ID, Round Type, Propellant lenght, Projectile lenght
- self.RoundId = Data1 --Weapon this round loads into, ie 140mmC, 105mmH ...
- self.RoundType = Data2 --Type of round, IE AP, HE, HEAT ...
- self.RoundPropellant = Data3--Lenght of propellant
- self.RoundProjectile = Data4--Lenght of the projectile
- self.RoundData5 = ( Data5 or 0 )
- self.RoundData6 = ( Data6 or 0 )
- self.RoundData7 = ( Data7 or 0 )
- self.RoundData8 = ( Data8 or 0 )
- self.RoundData9 = ( Data9 or 0 )
- self.RoundData10 = ( Data10 or 0 )
-
- local PlayerData = {}
- PlayerData["Id"] = self.RoundId
- PlayerData["Type"] = self.RoundType
- PlayerData["PropLength"] = self.RoundPropellant
- PlayerData["ProjLength"] = self.RoundProjectile
- PlayerData["Data5"] = self.RoundData5
- PlayerData["Data6"] = self.RoundData6
- PlayerData["Data7"] = self.RoundData7
- PlayerData["Data8"] = self.RoundData8
- PlayerData["Data9"] = self.RoundData9
- PlayerData["Data10"] = self.RoundData10
- self.ConvertData = ACF.RoundTypes[self.RoundType]["convert"]
- self.BulletData = self:ConvertData( PlayerData )
-
- local Size = (self:OBBMaxs() - self:OBBMins())
- local Efficiency = 0.11 * ACF.AmmoMod --This is the part of space that's actually useful, the rest is wasted on interround gaps, loading systems ..
- self.Volume = math.floor(Size.x * Size.y * Size.z)*Efficiency
- self.Capacity = math.floor(self.Volume*16.38/self.BulletData["RoundVolume"])
-
- self:SetNetworkedString("Ammo",self.Ammo)
-
- self.NetworkData = ACF.RoundTypes[self.RoundType]["network"]
- self:NetworkData( self.BulletData )
-
-end
-
-function ENT:AmmoMass() --Returns what the ammo mass would be if the crate was full
- return math.floor( (self.BulletData["ProjMass"] + self.BulletData["PropMass"]) * self.Capacity * 2 )
-end
-
-function ENT:TriggerInput( iname , value )
-
- if (iname == "Active") then
- if value > 0 then
- self.Load = true
- self:FirstLoad()
- else
- self.Load = false
- end
- end
-
-end
-
-function ENT:FirstLoad()
-
- for Key,Value in pairs(self.Master) do
- if self.Master[Key] and self.Master[Key]:IsValid() and self.Master[Key]["BulletData"]["Type"] == "Empty" then
- --print("Send FirstLoad")
- self.Master[Key]:UnloadAmmo()
- end
- end
-
-end
-
-function ENT:Think()
-
- local AmmoMass = self:AmmoMass()
- self.Mass = math.max(self.EmptyMass, self.Entity:GetPhysicsObject():GetMass() - AmmoMass) + AmmoMass*(self.Ammo/math.max(self.Capacity,1))
- self.Entity:GetPhysicsObject():SetMass(self.Mass)
-
- self:SetNetworkedString("Ammo",self.Ammo)
-
- local color = self.Entity:GetColor();
- self:SetNetworkedVector("TracerColour", Vector( color.r, color.g, color.b ) )
-
- local cvarGrav = GetConVar("sv_gravity")
- local vec = Vector(0,0,cvarGrav:GetInt()*-1)
- if( self.sitp_inspace ) then
- vec = Vector(0, 0, 0)
- end
-
- self:SetNetworkedVector("Accel", vec)
-
- self.Entity:NextThink( CurTime() + 1 )
-
- if self.Damaged then
- if self.Damaged < CurTime() then
- ACF_AmmoExplosion( self.Entity , self.Entity:GetPos() )
- else
- if math.Rand(0,150) > self.BulletData["RoundVolume"]^0.5 and math.Rand(0,1) < self.Ammo/math.max(self.Capacity,1) and ACF.RoundTypes[self.BulletData["Type"]] then
- self.Entity:EmitSound( "ambient/explosions/explode_4.wav" , 350 , math.max(255 - self.BulletData["PropMass"]*100,60) )
- local MuzzlePos = self.Entity:GetPos()
- local MuzzleVec = VectorRand()
- local Speed = ACF_MuzzleVelocity( self.BulletData["PropMass"], self.BulletData["ProjMass"]/2, self.Caliber )
-
- self.BulletData["Pos"] = MuzzlePos
- self.BulletData["Flight"] = (MuzzleVec):GetNormalized() * Speed * 39.37 + self:GetVelocity()
- self.BulletData["Owner"] = self.Owner
- self.BulletData["Gun"] = self.Entity
- self.BulletData["Crate"] = self.Entity:EntIndex()
- self.CreateShell = ACF.RoundTypes[self.BulletData["Type"]]["create"]
- self:CreateShell( self.BulletData )
-
- self.Ammo = self.Ammo - 1
-
- end
- self.Entity:NextThink( CurTime() + 0.01 + self.BulletData["RoundVolume"]^0.5/100 )
- end
- end
-
- Wire_TriggerOutput(self.Entity, "Munitions", self.Ammo)
- return true
-
-end
-
-function ENT:ConvertData()
- --You overwrite this with your own function, defined in the ammo definition file
-end
-
-function ENT:NetworkData()
- --You overwrite this with your own function, defined in the ammo definition file
-end
-
-function ENT:Touch( Supplier )
-
- if ( Supplier:GetClass() == "acf_ammo" ) then
-
- if ( Supplier.RoundType == "Refill" ) then
-
- local Supply = math.floor(Supplier.Ammo/self.BulletData["RoundVolume"])
-
- if self.Capacity > self.Ammo then
-
- local Transfert = math.min(Supply , self.Capacity - self.Ammo)
- --Msg("Reicever Ok " ..Transfert.. "\n")
- self.Ammo = self.Ammo + Transfert
- Supplier.Ammo = Supplier.Ammo - math.floor(Transfert*self.BulletData["RoundVolume"])
-
- self.Supplied = true
- self.Entity:EmitSound( "items/ammo_pickup.wav" , 500, 80 )
-
- if Transfer == Supply then
- Supplier:Remove()
- end
-
- end
-
- end
-
- end
-
-end
-
-function ENT:OnRemove()
- for Key,Value in pairs(self.Master) do
- if self.Master[Key] and self.Master[Key]:IsValid() then
- self.Master[Key]:Unlink( self.Entity )
- self.Ammo = 0
- end
- end
- Wire_Remove(self.Entity)
-end
-
-function ENT:OnRestore()
- Wire_Restored(self.Entity)
-end
-
-function ENT:PreEntityCopy()
- //Wire dupe info
- local DupeInfo = WireLib.BuildDupeInfo(self.Entity)
- if(DupeInfo) then
- duplicator.StoreEntityModifier(self.Entity,"WireDupeInfo",DupeInfo)
- end
-end
-
-function ENT:PostEntityPaste(Player,Ent,CreatedEntities)
- //Wire dupe info
- if(Ent.EntityMods and Ent.EntityMods.WireDupeInfo) then
- WireLib.ApplyDupeInfo(Player, Ent, Ent.EntityMods.WireDupeInfo, function(id) return CreatedEntities[id] end)
- end
-end
diff --git a/lua/entities/ACF_Ammo/shared.lua b/lua/entities/ACF_Ammo/shared.lua
deleted file mode 100644
index 306dc3679..000000000
--- a/lua/entities/ACF_Ammo/shared.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-ENT.Type = "anim"
-ENT.Base = "base_gmodentity"
-ENT.Author = "Kafouille"
-
-ENT.Spawnable = false
-ENT.AdminSpawnable = false
-
-
-
diff --git a/lua/entities/ACF_Engine/cl_init.lua b/lua/entities/ACF_Engine/cl_init.lua
deleted file mode 100644
index fe2115d0d..000000000
--- a/lua/entities/ACF_Engine/cl_init.lua
+++ /dev/null
@@ -1,71 +0,0 @@
-include("shared.lua")
-
-ENT.RenderGroup = RENDERGROUP_OPAQUE
-
-ENT.AutomaticFrameAdvance = true
-
-function ENT:Draw()
- self:DoNormalDraw()
- self:DrawModel()
- Wire_Render(self.Entity)
-end
-
-function ENT:DoNormalDraw()
- local e = self.Entity
- if (LocalPlayer():GetEyeTrace().Entity == e and EyePos():Distance(e:GetPos()) < 256) then
- if(self:GetOverlayText() ~= "") then
- AddWorldTip(e:EntIndex(),self:GetOverlayText(),0.5,e:GetPos(),e)
- end
- end
-end
-
-function ENT:GetOverlayText()
- local name = self.Entity:GetNetworkedString("WireName")
- local Type = self.Entity:GetNetworkedBeamString("Type")
- local Power = self.Entity:GetNetworkedBeamInt("Power")
- local Torque = self.Entity:GetNetworkedBeamInt("Torque")
- local MinRPM = self.Entity:GetNetworkedBeamInt("MinRPM")
- local MaxRPM = self.Entity:GetNetworkedBeamInt("MaxRPM")
- local LimitRPM = self.Entity:GetNetworkedBeamInt("LimitRPM")
- local txt = Type.."\nMax Power : "..Power.."KW / "..math.Round(Power*1.34).."HP \nMax Torque : "..Torque.."N/m / "..math.Round(Torque*0.73).."ft-lb \nPowerband : "..MinRPM.." - "..MaxRPM.."RPM\nRedline : "..LimitRPM.."RPM" or ""
- if (not game.SinglePlayer()) then
- local PlayerName = self:GetPlayerName()
- txt = txt .. "\n(" .. PlayerName .. ")"
- end
- if(name and name ~= "") then
- if (txt == "") then
- return "- "..name.." -"
- end
- return "- "..name.." -\n"..txt
- end
- return txt
-end
-
-function ACFEngineGUICreate( Table )
-
- acfmenupanel:CPanelText("Name", Table.name)
-
- acfmenupanel.CData.DisplayModel = vgui.Create( "DModelPanel", acfmenupanel.CustomDisplay )
- acfmenupanel.CData.DisplayModel:SetModel( Table.model )
- acfmenupanel.CData.DisplayModel:SetCamPos( Vector( 250 , 500 , 250 ) )
- acfmenupanel.CData.DisplayModel:SetLookAt( Vector( 0, 0, 0 ) )
- acfmenupanel.CData.DisplayModel:SetFOV( 20 )
- acfmenupanel.CData.DisplayModel:SetSize(acfmenupanel:GetWide(),acfmenupanel:GetWide())
- acfmenupanel.CData.DisplayModel.LayoutEntity = function( panel , entity ) end
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.DisplayModel )
-
- acfmenupanel:CPanelText("Desc", Table.desc)
-
- if (Table.iselec == true )then
- acfmenupanel:CPanelText("Power", "Peak Power : "..Table.elecpower.." kW / "..math.Round(Table.elecpower*1.34).." HP @ "..(Table.peakmaxrpm).." RPM")
- else
- acfmenupanel:CPanelText("Power", "Peak Power : "..(math.floor(Table.torque * Table.peakmaxrpm / 9548.8)).." kW / "..math.Round(math.floor(Table.torque * Table.peakmaxrpm / 9548.8)*1.34).." HP @ "..(Table.peakmaxrpm).." RPM")
- end
-
- acfmenupanel:CPanelText("Torque", "Peak Torque : "..(Table.torque).." n/m / "..math.Round(Table.torque*0.73).." ft-lb")
- acfmenupanel:CPanelText("RPM", "Idle : "..(Table.idlerpm).." RPM\nIdeal RPM Range : "..(Table.peakminrpm).."-"..(Table.peakmaxrpm).." RPM\nRedline : "..(Table.limitprm).." RPM")
- acfmenupanel:CPanelText("Weight", "Weight : "..(Table.weight).." kg")
-
- acfmenupanel.CustomDisplay:PerformLayout()
-
-end
\ No newline at end of file
diff --git a/lua/entities/ACF_Engine/init.lua b/lua/entities/ACF_Engine/init.lua
deleted file mode 100644
index 62fcfc791..000000000
--- a/lua/entities/ACF_Engine/init.lua
+++ /dev/null
@@ -1,473 +0,0 @@
-AddCSLuaFile( "shared.lua" )
-AddCSLuaFile( "cl_init.lua" )
-
-include('shared.lua')
-
-function ENT:Initialize()
-
- self.Throttle = 0
- self.Active = false
- self.IsMaster = true
- self.GearLink = {}
- self.GearRope = {}
-
- self.LastCheck = 0
- self.LastThink = 0
- self.Mass = 0
- self.PhysMass = 0
- self.MassRatio = 1
- self.Legal = true
- self.CanUpdate = true
-
- self.Inputs = Wire_CreateInputs( self.Entity, { "Active", "Throttle" } )
- self.Outputs = WireLib.CreateSpecialOutputs( self.Entity, { "RPM", "Torque", "Power", "Entity" , "Mass" , "Physical Mass" }, { "NORMAL" ,"NORMAL" ,"NORMAL" , "ENTITY" , "NORMAL" , "NORMAL" } )
- Wire_TriggerOutput(self.Entity, "Entity", self.Entity)
- self.WireDebugName = "ACF Engine"
-
-end
-
-function MakeACF_Engine(Owner, Pos, Angle, Id)
-
- if not Owner:CheckLimit("_acf_misc") then return false end
-
- local Engine = ents.Create("ACF_Engine")
- local List = list.Get("ACFEnts")
- local Classes = list.Get("ACFClasses")
- if not Engine:IsValid() then return false end
- Engine:SetAngles(Angle)
- Engine:SetPos(Pos)
- Engine:Spawn()
-
- Engine:SetPlayer(Owner)
- Engine.Owner = Owner
- Engine.Id = Id
- Engine.Model = List["Mobility"][Id]["model"]
- Engine.SoundPath = List["Mobility"][Id]["sound"]
- Engine.Weight = List["Mobility"][Id]["weight"]
- Engine.PeakTorque = List["Mobility"][Id]["torque"]
- Engine.IdleRPM = List["Mobility"][Id]["idlerpm"]
- Engine.PeakMinRPM = List["Mobility"][Id]["peakminrpm"]
- Engine.PeakMaxRPM = List["Mobility"][Id]["peakmaxrpm"]
- Engine.LimitRPM = List["Mobility"][Id]["limitprm"]
- Engine.Inertia = List["Mobility"][Id]["flywheelmass"]*(3.1416)^2
- Engine.iselec = List["Mobility"][Id]["iselec"]
- Engine.elecpower = List["Mobility"][Id]["elecpower"]
- Engine.FlywheelOverride = List["Mobility"][Id]["flywheeloverride"]
-
- Engine.FlyRPM = 0
- Engine:SetModel( Engine.Model )
- Engine.Sound = nil
- Engine.RPM = {}
-
- Engine:PhysicsInit( SOLID_VPHYSICS )
- Engine:SetMoveType( MOVETYPE_VPHYSICS )
- Engine:SetSolid( SOLID_VPHYSICS )
-
- Engine.Out = Engine:WorldToLocal(Engine:GetAttachment(Engine:LookupAttachment( "driveshaft" )).Pos)
-
- local phys = Engine:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:SetMass( Engine.Weight )
- end
-
- Engine:SetNetworkedBeamString("Type",List["Mobility"][Id]["name"])
- Engine:SetNetworkedBeamInt("Torque",Engine.PeakTorque)
- -- add in the variable to check if its an electric motor
- if (Engine.iselec == true )then
- Engine:SetNetworkedBeamInt("Power",Engine.elecpower) -- add in the value from the elecpower
- else
- Engine:SetNetworkedBeamInt("Power",math.floor(Engine.PeakTorque * Engine.PeakMaxRPM / 9548.8))
- end
- Engine:SetNetworkedBeamInt("MinRPM",Engine.PeakMinRPM)
- Engine:SetNetworkedBeamInt("MaxRPM",Engine.PeakMaxRPM)
- Engine:SetNetworkedBeamInt("LimitRPM",Engine.LimitRPM)
-
- undo.Create("ACF Engine")
- undo.AddEntity( Engine )
- undo.SetPlayer( Owner )
- undo.Finish()
-
- Owner:AddCount("_acf_engine", Engine)
- Owner:AddCleanup( "acfmenu", Engine )
-
- return Engine
-end
-list.Set( "ACFCvars", "acf_engine" , {"id"} )
-duplicator.RegisterEntityClass("acf_engine", MakeACF_Engine, "Pos", "Angle", "Id")
-
-function ENT:Update( ArgsTable ) --That table is the player data, as sorted in the ACFCvars above, with player who shot, and pos and angle of the tool trace inserted at the start
-
- local Feedback = "Engine updated"
- if self.Active then
- Feedback = "Please turn off the engine before updating it"
- return Feedback end
- if ( ArgsTable[1] != self.Owner ) then --Argtable[1] is the player that shot the tool
- Feedback = "You don't own that engine !"
- return Feedback end
-
- local Id = ArgsTable[4] --Argtable[4] is the engine ID
- local List = list.Get("ACFEnts")
-
- if ( List["Mobility"][Id]["model"] != self.Model ) then --Make sure the models are the sames before doing a changeover
- Feedback = "The new engine needs to have the same model as the old one !"
- return end
-
- self.Id = Id
- self.SoundPath = List["Mobility"][Id]["sound"]
- self.Weight = List["Mobility"][Id]["weight"]
- self.PeakTorque = List["Mobility"][Id]["torque"]
- self.IdleRPM = List["Mobility"][Id]["idlerpm"]
- self.PeakMinRPM = List["Mobility"][Id]["peakminrpm"]
- self.PeakMaxRPM = List["Mobility"][Id]["peakmaxrpm"]
- self.LimitRPM = List["Mobility"][Id]["limitprm"]
- self.Inertia = List["Mobility"][Id]["flywheelmass"]*(3.1416)^2
- self.iselec = List["Mobility"][Id]["iselec"] -- is the engine electric?
- self.elecpower = List["Mobility"][Id]["elecpower"] -- how much power does it output
- self.FlywheelOverride = List["Mobility"][Id]["flywheeloverride"] -- how much power does it output
-
- self:SetModel( self.Model )
- self:SetSolid( SOLID_VPHYSICS )
- self.Out = self:WorldToLocal(self:GetAttachment(self:LookupAttachment( "driveshaft" )).Pos)
-
- local phys = self:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:SetMass( self.Weight )
- end
-
- self:SetNetworkedBeamString("Type",List["Mobility"][Id]["name"])
- self:SetNetworkedBeamInt("Torque",self.PeakTorque)
- -- add in the variable to check if its an electric motor
- if (self.iselec == true) then
- self:SetNetworkedBeamInt("Power",self.elecpower) -- add in the value from the elecpower
- else
- self:SetNetworkedBeamInt("Power",math.floor(self.PeakTorque * self.PeakMaxRPM / 9548.8))
- end
-
- self:SetNetworkedBeamInt("MinRPM",self.PeakMinRPM)
- self:SetNetworkedBeamInt("MaxRPM",self.PeakMaxRPM)
- self:SetNetworkedBeamInt("LimitRPM",self.LimitRPM)
-
-
- return Feedback
-end
-
-function ENT:TriggerInput( iname , value )
-
- if (iname == "Throttle") then
- self.Throttle = math.Clamp(value,0,100)/100
- elseif (iname == "Active") then
- if (value > 0 and not self.Active) then
- self.Active = true
- self.Sound = CreateSound(self, self.SoundPath)
- self.Sound:PlayEx(0.5,100)
- self:ACFInit()
- elseif (value <= 0 and self.Active) then
- self.Active = false
- self.RPM = {}
- self.RPM[1] = self.IdleRPM
- if self.Sound then
- self.Sound:Stop()
- end
- self.Sound = nil
- end
- end
-
-
-end
-
-function ENT:Think()
-
- local Time = CurTime()
-
- if self.Active then
-
- if self.Legal then
- local EngPhys = self:GetPhysicsObject()
- local RPM = self:CalcRPM( EngPhys )
- end
-
- if self.LastCheck < CurTime() then
- self:CheckRopes()
- if self.Entity:GetPhysicsObject():GetMass() < self.Weight or self.Entity:GetParent():IsValid() then
- self.Legal = false
- else
- self.Legal = true
- end
-
- self.LastCheck = Time + math.Rand(5,10)
- end
-
- end
-
- self.LastThink = Time
- self.Entity:NextThink(Time)
- return true
-
-end
-
-function ENT:ACFInit()
-
- if not constraint.HasConstraints(self) then return end
-
- local Constrained = constraint.GetAllConstrainedEntities(self)
- self.Mass = 0
- self.PhysMass = 0
-
- for _,Ent in pairs(Constrained) do
-
- if IsValid(Ent) then
- local Phys = Ent:GetPhysicsObject()
-
- if Phys and Phys:IsValid() then
- self.Mass = self.Mass + Phys:GetMass()
- local Parent = Ent:GetParent()
-
- if IsValid(Parent) then
-
- local Constraints = {}
- table.Add(Constraints,constraint.FindConstraints(Ent, "Weld"))
- table.Add(Constraints,constraint.FindConstraints(Ent, "Axis"))
- table.Add(Constraints,constraint.FindConstraints(Ent, "Ballsocket"))
- table.Add(Constraints,constraint.FindConstraints(Ent, "AdvBallsocket"))
-
- if Constraints then
-
- for Key,Const in pairs(Constraints) do
-
- if Const.Ent1 == Parent or Const.Ent2 == Parent then
- self.PhysMass = self.PhysMass + Phys:GetMass()
- end
-
- end
-
- end
-
- else
- self.PhysMass = self.PhysMass + Phys:GetMass()
- end
-
- end
-
- end
-
- end
-
- self.MassRatio = self.PhysMass/self.Mass
-
- Wire_TriggerOutput(self.Entity, "Mass", math.floor(self.Mass))
- Wire_TriggerOutput(self.Entity, "Physical Mass", math.floor(self.PhysMass))
-
- self.LastThink = CurTime()
- self.Torque = self.PeakTorque
- self.FlyRPM = self.IdleRPM*1.5
-
-end
-
-function ENT:CalcRPM( EngPhys )
-
- local DeltaTime = (CurTime() - self.LastThink)
- local AutoClutch = math.min(math.max(self.FlyRPM-self.IdleRPM,0)/(self.IdleRPM+self.LimitRPM/10),1)
-
- //local ClutchRatio = math.min(Clutch/math.max(TorqueDiff,0.05),1)
- self.Torque = self.Throttle * math.max( self.PeakTorque * math.min( self.FlyRPM/self.PeakMinRPM , (self.LimitRPM - self.FlyRPM)/(self.LimitRPM - self.PeakMaxRPM), 1 ),0 ) --Calculate the current torque from flywheel RPM
- --local Drag = self.PeakTorque*(math.max(self.FlyRPM-self.IdleRPM,0)/self.PeakMaxRPM)*(1-self.Throttle) /self.Inertia
- local Drag
- if (self.iselec == true) then
- Drag = self.PeakTorque*(math.max(self.FlyRPM-self.IdleRPM,0)/self.FlywheelOverride)*(1-self.Throttle) /self.Inertia
- else
- Drag = self.PeakTorque*(math.max(self.FlyRPM-self.IdleRPM,0)/self.PeakMaxRPM)*(1-self.Throttle) /self.Inertia
- end
- self.FlyRPM = math.max(self.FlyRPM + self.Torque/self.Inertia - Drag,1) --Let's accelerate the flywheel based on that torque
-
- local Boxes = table.Count(self.GearLink) --The gearboxes don't think on their own, it's the engine that calls them, to ensure consistent execution order
- local MaxTqTable = {}
- local MaxTq = 0
- for Key, Gearbox in pairs(self.GearLink) do
- MaxTqTable[Key] = Gearbox:Calc( self.FlyRPM, self.Inertia ) --Get the requirements for torque for the gearboxes (Max clutch rating minus any wheels currently spinning faster than the Flywheel)
- MaxTq = MaxTq + MaxTqTable[Key]
- end
-
- local TorqueDiff = math.max(self.FlyRPM - self.IdleRPM,0)*self.Inertia --This is the presently avaliable torque from the engine
- local AvailTq = math.min(TorqueDiff/MaxTq/Boxes,1) --Calculate the ratio of total requested torque versus what's avaliable
-
- for Key, Gearbox in pairs(self.GearLink) do
- Gearbox:Act(MaxTqTable[Key]*AvailTq*self.MassRatio,DeltaTime) --Split the torque fairly between the gearboxes who need it
- end
-
- self.FlyRPM = self.FlyRPM - (math.min(TorqueDiff,MaxTq)/self.Inertia)
-
- table.remove( self.RPM, 10 ) --Then we calc a smoothed RPM value for the sound effects
- table.insert( self.RPM, 1, self.FlyRPM )
- local SmoothRPM = 0
- for Key, RPM in pairs(self.RPM) do
- SmoothRPM = SmoothRPM + (RPM or 0)
- end
- SmoothRPM = SmoothRPM/10
-
- local Power = self.Torque * SmoothRPM / 9548.8
- Wire_TriggerOutput(self.Entity, "Torque", math.floor(self.Torque))
- Wire_TriggerOutput(self.Entity, "Power", math.floor(Power))
- Wire_TriggerOutput(self.Entity, "RPM", self.FlyRPM)
- self.Sound:ChangePitch(math.min(20 + SmoothRPM/50,255),0)
- self.Sound:ChangeVolume(0.25 + self.Throttle/1.5,0)
-
- return RPM
-
-end
-
-function ENT:CheckRopes()
-
- for GearboxKey,Ent in pairs(self.GearLink) do
- local Constraints = constraint.FindConstraints(Ent, "Rope")
- if Constraints then
-
- local Clean = false
- for Key,Rope in pairs(Constraints) do
- if Rope.Ent1 == self.Entity or Rope.Ent2 == self.Entity then
- if Rope.length + Rope.addlength < self.GearRope[GearboxKey]*1.5 then
- Clean = true
- end
- end
- end
-
- if not Clean then
- self:Unlink( Ent )
- end
-
- else
- self:Unlink( Ent )
- end
-
- local DrvAngle = (self.Entity:LocalToWorld(self.Out) - Ent:LocalToWorld(Ent.In)):GetNormalized():DotProduct( self:GetForward() )
- if ( DrvAngle < 0.7 ) then
- self:Unlink( Ent )
- end
-
- end
-
-end
-
-function ENT:Link( Target )
-
- if ( !Target or Target:GetClass() != "acf_gearbox" ) then return ("Can only link to Gearboxes") end
-
- local Duplicate = false
- for Key,Value in pairs(self.GearLink) do
- if Value == Target then
- Duplicate = true
- end
- end
-
- if not Duplicate then
-
- local InPos = Target:LocalToWorld(Target.In)
- local OutPos = self.Entity:LocalToWorld(self.Out)
- local DrvAngle = (OutPos - InPos):GetNormalized():DotProduct((self:GetForward()))
- if ( DrvAngle < 0.7 ) then
- return 'ERROR : Excessive driveshaft angle'
- end
-
- table.insert(self.GearLink,Target)
- table.insert(Target.Master,self.Entity)
- local RopeL = (OutPos-InPos):Length()
- constraint.Rope( self.Entity, Target, 0, 0, self.Out, Target.In, RopeL, RopeL*0.2, 0, 1, "cable/cable2", false )
- table.insert(self.GearRope,RopeL)
-
- return false
- else
- return ('ERROR : Gearbox already linked to this Engine')
- end
-
-
-end
-
-function ENT:Unlink( Target )
-
- local Success = false
- for Key,Value in pairs(self.GearLink) do
- if Value == Target then
-
- local Constraints = constraint.FindConstraints(Value, "Rope")
- if Constraints then
- for Key,Rope in pairs(Constraints) do
- if Rope.Ent1 == self.Entity or Rope.Ent2 == self.Entity then
- Rope.Constraint:Remove()
- end
- end
- end
-
- table.remove(self.GearLink,Key)
- table.remove(self.GearRope,Key)
- Success = true
- end
- end
-
- if Success then
- return false
- else
- return ('ERROR : Did not find the Gearbox to unlink')
- end
-
-end
-
-function ENT:PreEntityCopy()
-
- //Link Saving
- local info = {}
- local entids = {}
- for Key, Value in pairs(self.GearLink) do --First clean the table of any invalid entities
- if not Value:IsValid() then
- table.remove(self.GearLink, Value)
- end
- end
- for Key, Value in pairs(self.GearLink) do --Then save it
- table.insert(entids, Value:EntIndex())
- end
-
- info.entities = entids
- if info.entities then
- duplicator.StoreEntityModifier( self.Entity, "GearLink", info )
- end
-
- //Wire dupe info
- local DupeInfo = WireLib.BuildDupeInfo(self.Entity)
- if(DupeInfo) then
- duplicator.StoreEntityModifier(self.Entity,"WireDupeInfo",DupeInfo)
- end
-
-end
-
-function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
-
- //Link Pasting
- if (Ent.EntityMods) and (Ent.EntityMods.GearLink) and (Ent.EntityMods.GearLink.entities) then
- local GearLink = Ent.EntityMods.GearLink
- if GearLink.entities and table.Count(GearLink.entities) > 0 then
- for _,ID in pairs(GearLink.entities) do
- local Linked = CreatedEntities[ ID ]
- if Linked and Linked:IsValid() then
- self:Link( Linked )
- end
- end
- end
- Ent.EntityMods.GearLink = nil
- end
-
- //Wire dupe info
- if(Ent.EntityMods and Ent.EntityMods.WireDupeInfo) then
- WireLib.ApplyDupeInfo(Player, Ent, Ent.EntityMods.WireDupeInfo, function(id) return CreatedEntities[id] end)
- end
-
-end
-
-function ENT:OnRemove()
- if self.Sound then
- self.Sound:Stop()
- end
- Wire_Remove(self.Entity)
-end
-
-function ENT:OnRestore()
- Wire_Restored(self.Entity)
-end
-
diff --git a/lua/entities/ACF_Engine/shared.lua b/lua/entities/ACF_Engine/shared.lua
deleted file mode 100644
index 528853167..000000000
--- a/lua/entities/ACF_Engine/shared.lua
+++ /dev/null
@@ -1,8 +0,0 @@
-ENT.Type = "anim"
-ENT.Base = "base_gmodentity"
-ENT.Author = "Kafouille"
-
-ENT.Spawnable = false
-ENT.AdminSpawnable = false
-
-
diff --git a/lua/entities/ACF_Gearbox/cl_init.lua b/lua/entities/ACF_Gearbox/cl_init.lua
deleted file mode 100644
index 58d4fedd9..000000000
--- a/lua/entities/ACF_Gearbox/cl_init.lua
+++ /dev/null
@@ -1,103 +0,0 @@
-include("shared.lua")
-
-ENT.RenderGroup = RENDERGROUP_OPAQUE
-local maxtorque = 0 -- this is for the max torque output on the tooltip - Wrex
-function ENT:Draw()
- self:DoNormalDraw()
- Wire_Render(self.Entity)
-end
-
-function ENT:DoNormalDraw()
- local e = self.Entity
- if (LocalPlayer():GetEyeTrace().Entity == e and EyePos():Distance(e:GetPos()) < 256) then
- if not self.DisplayString then self.DisplayString = "" end
- AddWorldTip(e:EntIndex(),self.DisplayString,0.5,e:GetPos(),e)
- end
- e:DrawModel()
-end
-
-function ACFGearboxCreateDisplayString( data, Timer )
-
- local Ent = data:ReadEntity()
- local Id = data:ReadString()
- local List = list.Get("ACFEnts")
- local FinalGear = data:ReadShort()/100
-
- Ent.DisplayString = List["Mobility"][Id]["name"].."\n"
- for I = 1,List["Mobility"][Id]["gears"] do
- Ent.DisplayString = Ent.DisplayString.."Gear "..I.." : "..tostring(data:ReadShort()/100).."\n"
- end
- Ent.DisplayString = Ent.DisplayString.."Final Gear : "..tostring(FinalGear).."\n Maximum Torque Rating: "..(maxtorque).."n-m / "..math.Round(maxtorque*0.73).."ft-lb"
- if data:ReadBool() then
- Ent:SetBodygroup(1,1)
- else
- Ent:SetBodygroup(1,0)
- end
-
- if (not game.SinglePlayer()) then
- local PlayerName = Ent:GetPlayerName()
- Ent.DisplayString = Ent.DisplayString .."(" .. PlayerName .. ")"
- end
-
-end
-usermessage.Hook( "ACFGearbox_SendRatios", ACFGearboxCreateDisplayString )
-
-function ACFGearboxGUICreate( Table )
-
- if not acfmenupanel.GearboxData then
- acfmenupanel.GearboxData = {}
- end
- if not acfmenupanel.GearboxData[Table.id] then
- acfmenupanel.GearboxData[Table.id] = {}
- acfmenupanel.GearboxData[Table.id]["GearTable"] = Table.geartable
- end
-
- acfmenupanel:CPanelText("Name", Table.name)
-
- acfmenupanel.CData.DisplayModel = vgui.Create( "DModelPanel", acfmenupanel.CustomDisplay )
- acfmenupanel.CData.DisplayModel:SetModel( Table.model )
- acfmenupanel.CData.DisplayModel:SetCamPos( Vector( 250 , 500 , 250 ) )
- acfmenupanel.CData.DisplayModel:SetLookAt( Vector( 0, 0, 0 ) )
- acfmenupanel.CData.DisplayModel:SetFOV( 20 )
- acfmenupanel.CData.DisplayModel:SetSize(acfmenupanel:GetWide(),acfmenupanel:GetWide())
- acfmenupanel.CData.DisplayModel.LayoutEntity = function( panel , entity ) end
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.DisplayModel )
-
- acfmenupanel:CPanelText("Desc", Table.desc) --Description (Name, Desc)
-
- for ID,Value in pairs(acfmenupanel.GearboxData[Table.id]["GearTable"]) do
- if ID > 0 then
- ACF_GearsSlider(ID, Value, Table.id)
- elseif ID == -1 then
- ACF_GearsSlider(10, Value, Table.id, "Final Drive")
- end
- end
-
- acfmenupanel:CPanelText("Desc", Table.desc)
- acfmenupanel:CPanelText("MaxTorque", "Clutch Maximum Torque Rating : "..(Table.maxtq).."n-m / "..math.Round(Table.maxtq*0.73).."ft-lb")
- acfmenupanel:CPanelText("Weight", "Weight : "..Table.weight.."kg")
-
- acfmenupanel.CustomDisplay:PerformLayout()
- maxtorque = Table.maxtq
-end
-
-function ACF_GearsSlider(Gear, Value, ID, Desc)
-
- if Gear and not acfmenupanel["CData"][Gear] then
- acfmenupanel["CData"][Gear] = vgui.Create( "DNumSlider", acfmenupanel.CustomDisplay )
- acfmenupanel["CData"][Gear]:SetText( Desc or "Gear "..Gear )
- acfmenupanel["CData"][Gear]:SetMin( -1 )
- acfmenupanel["CData"][Gear]:SetMax( 1 )
- acfmenupanel["CData"][Gear]:SetDecimals( 2 )
- acfmenupanel["CData"][Gear]["Gear"] = Gear
- acfmenupanel["CData"][Gear]["ID"] = ID
- acfmenupanel["CData"][Gear]:SetValue(Value)
- RunConsoleCommand( "acfmenu_data"..Gear, Value )
- acfmenupanel["CData"][Gear].OnValueChanged = function( slider, val )
- acfmenupanel.GearboxData[slider.ID]["GearTable"][slider.Gear] = val
- RunConsoleCommand( "acfmenu_data"..Gear, val )
- end
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel["CData"][Gear] )
- end
-
-end
\ No newline at end of file
diff --git a/lua/entities/ACF_Gearbox/init.lua b/lua/entities/ACF_Gearbox/init.lua
deleted file mode 100644
index 82d4eb666..000000000
--- a/lua/entities/ACF_Gearbox/init.lua
+++ /dev/null
@@ -1,580 +0,0 @@
-AddCSLuaFile( "shared.lua" )
-AddCSLuaFile( "cl_init.lua" )
-
-include('shared.lua')
-
-function ENT:Initialize()
-
- self.IsGeartrain = true
- self.Master = {}
-
- self.IsMaster = {}
- self.WheelLink = {}
- self.WheelSide = {}
- self.WheelCount = {}
- self.WheelAxis = {}
- self.WheelRopeL = {}
- self.WheelOutput = {}
- self.WheelReqTq = {}
- self.WheelVel = {}
-
- self.TotalReqTq = 0
- self.RClutch = 0
- self.LClutch = 0
- self.LBrake = 0
- self.RBrake = 0
-
- self.Gear = 1
- self.GearRatio = 0
- self.ChangeFinished = 0
-
- self.LegalThink = 0
-
- self.RPM = {}
- self.CurRPM = 0
- self.InGear = false
- self.CanUpdate = true
- self.LastActive = 0
- self.Legal = true
-
-end
-
-function MakeACF_Gearbox(Owner, Pos, Angle, Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
-
- if not Owner:CheckLimit("_acf_misc") then return false end
-
- local Gearbox = ents.Create("ACF_Gearbox")
- local List = list.Get("ACFEnts")
- local Classes = list.Get("ACFClasses")
- if not Gearbox:IsValid() then return false end
- Gearbox:SetAngles(Angle)
- Gearbox:SetPos(Pos)
- Gearbox:Spawn()
-
- Gearbox:SetPlayer(Owner)
- Gearbox.Owner = Owner
- Gearbox.Id = Id
- Gearbox.Model = List["Mobility"][Id]["model"]
- Gearbox.Mass = List["Mobility"][Id]["weight"]
- Gearbox.SwitchTime = List["Mobility"][Id]["switch"]
- Gearbox.MaxTorque = List["Mobility"][Id]["maxtq"]
- Gearbox.Gears = List["Mobility"][Id]["gears"]
- Gearbox.Dual = List["Mobility"][Id]["doubleclutch"]
- Gearbox.GearTable = List["Mobility"][Id]["geartable"]
- Gearbox.GearTable["Final"] = Data10
- Gearbox.GearTable[1] = Data1
- Gearbox.GearTable[2] = Data2
- Gearbox.GearTable[3] = Data3
- Gearbox.GearTable[4] = Data4
- Gearbox.GearTable[5] = Data5
- Gearbox.GearTable[6] = Data6
- Gearbox.GearTable[7] = Data7
- Gearbox.GearTable[8] = Data8
- Gearbox.GearTable[9] = Data9
- Gearbox.GearTable[0] = 0
-
- Gearbox.Gear0 = Data10
- Gearbox.Gear1 = Data1
- Gearbox.Gear2 = Data2
- Gearbox.Gear3 = Data3
- Gearbox.Gear4 = Data4
- Gearbox.Gear5 = Data5
- Gearbox.Gear6 = Data6
- Gearbox.Gear7 = Data7
- Gearbox.Gear8 = Data8
- Gearbox.Gear9 = Data9
-
- Gearbox:SetModel( Gearbox.Model )
-
- local Inputs = {"Gear","Gear Up","Gear Down"}
- if Gearbox.Dual then
- table.insert(Inputs,"Left Clutch")
- table.insert(Inputs,"Right Clutch")
- table.insert(Inputs,"Left Brake")
- table.insert(Inputs,"Right Brake")
- else
- table.insert(Inputs, "Clutch")
- table.insert(Inputs, "Brake")
- end
-
- Gearbox.Inputs = Wire_CreateInputs( Gearbox.Entity, Inputs )
- Gearbox.Outputs = WireLib.CreateSpecialOutputs( Gearbox.Entity, { "Ratio", "Entity" , "Current Gear" }, { "NORMAL" , "ENTITY" , "NORMAL" , "NORMAL" } )
- Wire_TriggerOutput(Gearbox.Entity, "Entity", Gearbox.Entity)
- Gearbox.WireDebugName = "ACF Gearbox"
-
- Gearbox.LClutch = Gearbox.MaxTorque
- Gearbox.RClutch = Gearbox.MaxTorque
-
- Gearbox:PhysicsInit( SOLID_VPHYSICS )
- Gearbox:SetMoveType( MOVETYPE_VPHYSICS )
- Gearbox:SetSolid( SOLID_VPHYSICS )
-
- local phys = Gearbox:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:SetMass( Gearbox.Mass )
- end
-
- Gearbox.In = Gearbox:WorldToLocal(Gearbox:GetAttachment(Gearbox:LookupAttachment( "input" )).Pos)
- Gearbox.OutL = Gearbox:WorldToLocal(Gearbox:GetAttachment(Gearbox:LookupAttachment( "driveshaftL" )).Pos)
- Gearbox.OutR = Gearbox:WorldToLocal(Gearbox:GetAttachment(Gearbox:LookupAttachment( "driveshaftR" )).Pos)
-
- undo.Create("ACF Gearbox")
- undo.AddEntity( Gearbox )
- undo.SetPlayer( Owner )
- undo.Finish()
-
- Owner:AddCount("_acf_Gearbox", Gearbox)
- Owner:AddCleanup( "acfmenu", Gearbox )
-
- Gearbox:ChangeGear(1)
-
- timer.Simple(0.5, function() Gearbox:UpdateHUD() end )
-
- return Gearbox
-end
-list.Set( "ACFCvars", "acf_gearbox" , {"id", "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9", "data10"} )
-duplicator.RegisterEntityClass("acf_gearbox", MakeACF_Gearbox, "Pos", "Angle", "Id", "Gear1", "Gear2", "Gear3", "Gear4", "Gear5", "Gear6", "Gear7", "Gear8", "Gear9", "Gear0" )
-
-function ENT:Update( ArgsTable ) --That table is the player data, as sorted in the ACFCvars above, with player who shot, and pos and angle of the tool trace inserted at the start
-
- local Feedback = "Gearbox updated successfully"
- if ( ArgsTable[1] != self.Owner ) then --Argtable[1] is the player that shot the tool
- Feedback = "You don't own that gearbox !"
- return Feedback end
-
- local Id = ArgsTable[4] --Argtable[4] is the engine ID
- local List = list.Get("ACFEnts")
-
- if ( List["Mobility"][Id]["model"] != self.Model ) then --Make sure the models are the sames before doing a changeover
- Feedback = "The new gearbox needs to have the same size and orientation as the old one !"
- return Feedback end
-
- if self.Id != Id then
- local Inputs = {"Gear","Gear Up","Gear Down"}
- if self.Dual then
- table.insert(Inputs,"Left Clutch")
- table.insert(Inputs,"Right Clutch")
- table.insert(Inputs,"Left Brake")
- table.insert(Inputs,"Right Brake")
- else
- table.insert(Inputs, "Clutch")
- table.insert(Inputs, "Brake")
- end
-
- self.Id = Id
- self.Mass = List["Mobility"][Id]["weight"]
- self.SwitchTime = List["Mobility"][Id]["switch"]
- self.MaxTorque = List["Mobility"][Id]["maxtq"]
- self.Gears = List["Mobility"][Id]["gears"]
- self.Dual = List["Mobility"][Id]["doubleclutch"]
-
- self.Inputs = Wire_CreateInputs( self.Entity, Inputs )
-
- end
-
- self.GearTable["Final"] = ArgsTable[14]
- self.GearTable[1] = ArgsTable[5]
- self.GearTable[2] = ArgsTable[6]
- self.GearTable[3] = ArgsTable[7]
- self.GearTable[4] = ArgsTable[8]
- self.GearTable[5] = ArgsTable[9]
- self.GearTable[6] = ArgsTable[10]
- self.GearTable[7] = ArgsTable[11]
- self.GearTable[8] = ArgsTable[12]
- self.GearTable[9] = ArgsTable[13]
- self.GearTable[0] = 0
-
- self.Gear0 = ArgsTable[14]
- self.Gear1 = ArgsTable[5]
- self.Gear2 = ArgsTable[6]
- self.Gear3 = ArgsTable[7]
- self.Gear4 = ArgsTable[8]
- self.Gear5 = ArgsTable[9]
- self.Gear6 = ArgsTable[10]
- self.Gear7 = ArgsTable[11]
- self.Gear8 = ArgsTable[12]
- self.Gear9 = ArgsTable[13]
-
- self:ChangeGear(1)
-
- self:UpdateHUD()
-
- return Feedback
-end
-
-function ENT:UpdateHUD()
-
- umsg.Start( "ACFGearbox_SendRatios", ply )
- umsg.Entity( self.Entity )
- umsg.String( self.Id )
- umsg.Short( self.Gear0*100 )
- for I=1 , self.Gears do
- umsg.Short( self.GearTable[I]*100 )
- end
- umsg.Bool( self.Dual )
- umsg.End()
-
-end
-
-function ENT:TriggerInput( iname , value )
-
- if ( iname == "Gear" and self.Gear != math.floor(value) ) then
- self:ChangeGear(math.floor(value))
- elseif ( iname == "Gear Up" ) then
- if ( self.Gear < self.Gears and value > 0 ) then
- self:ChangeGear(math.floor(self.Gear + 1))
- end
- elseif ( iname == "Gear Down" ) then
- if ( self.Gear > 1 and value > 0 ) then
- self:ChangeGear(math.floor(self.Gear - 1))
- end
- elseif ( iname == "Clutch" ) then
- self.LClutch = math.Clamp(1-value,0,1)*self.MaxTorque
- self.RClutch = math.Clamp(1-value,0,1)*self.MaxTorque
- elseif ( iname == "Brake" ) then
- self.LBrake = math.Clamp(value,0,100)
- self.RBrake = math.Clamp(value,0,100)
- elseif ( iname == "Left Brake" ) then
- self.LBrake = math.Clamp(value,0,100)
- elseif ( iname == "Right Brake" ) then
- self.RBrake = math.Clamp(value,0,100)
- elseif ( iname == "Left Clutch" ) then
- self.LClutch = math.Clamp(1-value,0,1)*self.MaxTorque
- elseif ( iname == "Right Clutch" ) then
- self.RClutch = math.Clamp(1-value,0,1)*self.MaxTorque
- end
-
-end
-
-function ENT:Think()
-
- local Time = CurTime()
-
- if self.LegalThink < Time and self.LastActive+2 > Time then
- self:CheckRopes()
- if self.Entity:GetPhysicsObject():GetMass() < self.Mass or self.Entity:GetParent():IsValid() then
- self.Legal = false
- else
- self.Legal = true
- end
- self.LegalThink = Time + (math.random(5,10))
- end
-
- self.Entity:NextThink(Time+0.2)
- return true
-
-end
-
-function ENT:CheckRopes()
-
- for WheelKey,Ent in pairs(self.WheelLink) do
- local Constraints = constraint.FindConstraints(Ent, "Rope")
- if Constraints then
-
- local Clean = false
- for Key,Rope in pairs(Constraints) do
- if Rope.Ent1 == self.Entity or Rope.Ent2 == self.Entity then
- if Rope.length + Rope.addlength < self.WheelRopeL[WheelKey]*1.5 then
- Clean = true
- end
- end
- end
-
- if not Clean then
- self:Unlink( Ent )
- end
-
- else
- self:Unlink( Ent )
- end
-
- local DrvAngle = (self.Entity:LocalToWorld(self.WheelOutput[WheelKey]) - Ent:GetPos()):GetNormalized():DotProduct( (self:GetRight()*self.WheelOutput[WheelKey].y):GetNormalized() )
- if ( DrvAngle < 0.7 ) then
- self:Unlink( Ent )
- end
- end
-
-end
-
-function ENT:CheckEnts() --Check if every entity we are linked to still actually exists
-
- for Key, WheelEnt in pairs(self.WheelLink) do
- if not IsValid(WheelEnt) then
- table.remove(self.WheelAxis,Key)
- table.remove(self.WheelSide,Key)
- else
- local WheelPhys = WheelEnt:GetPhysicsObject()
- if not IsValid(WheelPhys) then
- WheelEnt:Remove()
- table.remove(self.WheelAxis,Key)
- table.remove(self.WheelSide,Key)
- end
- end
- end
-
-end
-
-function ENT:Calc( InputRPM, InputInertia )
-
- if self.LastActive == CurTime() then return math.min(self.TotalReqTq, self.MaxTorque) end
- if self.ChangeFinished < CurTime() and self.GearRatio != 0 then
- self.InGear = true
- else return 0 end
-
- self:CheckEnts()
-
- local BoxPhys = self:GetPhysicsObject()
- local SelfWorld = self:LocalToWorld(BoxPhys:GetAngleVelocity())-self:GetPos()
- self.WheelReqTq = {}
- self.TotalReqTq = 0
-
- for Key, WheelEnt in pairs(self.WheelLink) do
- if ( WheelEnt:IsValid() ) then
- local Clutch = 0
- if self.WheelSide[Key] == 0 then
- Clutch = self.LClutch
- elseif self.WheelSide[Key] == 1 then
- Clutch = self.RClutch
- end
-
- self.WheelReqTq[Key] = 0
- if WheelEnt.IsGeartrain then
- self.WheelReqTq[Key] = math.abs(WheelEnt:Calc( InputRPM*self.GearRatio, InputInertia/self.GearRatio )*self.GearRatio)
- else
- local RPM = self:CalcWheel( Key, WheelEnt, SelfWorld )
- if (InputRPM > 0 and RPM < InputRPM) or (InputRPM < 0 and RPM > InputRPM) then
- self.WheelReqTq[Key] = math.min(Clutch, (InputRPM - RPM)*InputInertia )
- end
- end
- self.TotalReqTq = self.TotalReqTq + self.WheelReqTq[Key]
- else
- table.remove(self.WheelLink, Key)
- end
- end
-
- return math.min(self.TotalReqTq, self.MaxTorque)
-
-end
-
-function ENT:CalcWheel( Key, WheelEnt, SelfWorld )
- if ( WheelEnt:IsValid() ) then
- local WheelPhys = WheelEnt:GetPhysicsObject()
- local VelDiff = (WheelEnt:LocalToWorld(WheelPhys:GetAngleVelocity())-WheelEnt:GetPos()) - SelfWorld
- local BaseRPM = VelDiff:Dot(WheelEnt:LocalToWorld(self.WheelAxis[Key])-WheelEnt:GetPos())
- local GearedRPM = BaseRPM / self.GearRatio / -6 --Reported BaseRPM is in angle per second and in the wrong direction, so we convert and add the gearratio
- self.WheelVel[Key] = BaseRPM
-
- return GearedRPM
- else
- return 0
- end
-
-end
-
-function ENT:Act( Torque, DeltaTime )
-
- local ReactTq = 0
- --local AvailTq = math.min(math.abs(Torque)/self.TotalReqTq,1)/self.GearRatio*-(-Torque/math.abs(Torque)) --Calculate the ratio of total requested torque versus what's avaliable, and then multiply it but the current gearratio
- local AvailTq = 0
- if Torque != 0 then
- AvailTq = math.min(math.abs(Torque)/self.TotalReqTq,1)/self.GearRatio*-(-Torque/math.abs(Torque))
- end
-
-
- for Key, OutputEnt in pairs(self.WheelLink) do
- if self.WheelSide[Key] == 0 then
- Brake = self.LBrake
- elseif self.WheelSide[Key] == 1 then
- Brake = self.RBrake
- end
-
- if OutputEnt.IsGeartrain then
- OutputEnt:Act( self.WheelReqTq[Key]*AvailTq , DeltaTime )
- else
- self:ActWheel( Key, OutputEnt, self.WheelReqTq[Key]*AvailTq, Brake , DeltaTime )
- ReactTq = ReactTq + self.WheelReqTq[Key]*AvailTq
- end
- end
-
- local BoxPhys = self:GetPhysicsObject()
- if BoxPhys:IsValid() and ReactTq != 0 then
- local Force = self:GetForward() * ReactTq - self:GetForward() * BrakeMult
- BoxPhys:ApplyForceOffset( Force * 39.37 * DeltaTime, self:GetPos() + self:GetUp()*-39.37 )
- BoxPhys:ApplyForceOffset( Force * -39.37 * DeltaTime, self:GetPos() + self:GetUp()*39.37 )
- end
-
- self.LastActive = CurTime()
-
-end
-
-function ENT:ActWheel( Key, OutputEnt, Tq, Brake , DeltaTime )
-
- local OutPhys = OutputEnt:GetPhysicsObject()
- local OutPos = OutputEnt:GetPos()
- local TorqueAxis = OutputEnt:LocalToWorld(self.WheelAxis[Key]) - OutPos
- local Cross = TorqueAxis:Cross( Vector(TorqueAxis.y,TorqueAxis.z,TorqueAxis.x) )
- local Inertia = OutPhys:GetInertia()
- local BrakeMult = 0
- if Brake > 0 then
- BrakeMult = self.WheelVel[Key] * Inertia * Brake / 10
- end
- local TorqueVec = TorqueAxis:Cross(Cross):GetNormalized()
- local Force = TorqueVec * Tq + TorqueVec * BrakeMult
- OutPhys:ApplyForceOffset( Force * -39.37 * DeltaTime, OutPos + Cross*39.37)
- OutPhys:ApplyForceOffset( Force * 39.37 * DeltaTime, OutPos + Cross*-39.37 )
-
-end
-
-function ENT:ChangeGear(value)
-
- self.Gear = math.Clamp(value,0,self.Gears)
- self.GearRatio = (self.GearTable[self.Gear] or 0)*self.GearTable["Final"]
- self.ChangeFinished = CurTime() + self.SwitchTime
- self.InGear = false
-
- Wire_TriggerOutput(self.Entity, "Current Gear", self.Gear)
- self:EmitSound("buttons/lever7.wav",250,100)
- Wire_TriggerOutput(self.Entity, "Ratio", self.GearRatio)
-
-end
-
-function ENT:Link( Target )
-
- if ( !Target or (Target:GetClass() != "prop_physics" and Target:GetClass() != "acf_gearbox") ) then return "Can only link plain props or other gearboxes" end
-
- for Key,Value in pairs(self.WheelLink) do
- if Value == Target then return "This is already linked to this gearbox !" end
- end
-
- local TargetPos = Target:GetPos()
- if Target.IsGeartrain then
- TargetPos = Target:LocalToWorld(Target.In)
- end
- local LinkPos = Vector(0,0,0)
- local Side = 0
- if self.Entity:WorldToLocal(TargetPos).y < 0 then
- LinkPos = self.OutL
- Side = 0
- else
- LinkPos = self.OutR
- Side = 1
- end
-
- local DrvAngle = (self.Entity:LocalToWorld(LinkPos) - TargetPos):GetNormalized():DotProduct( (self:GetRight()*LinkPos.y):GetNormalized() )
- if ( DrvAngle < 0.7 ) then
- return "Cannot link due to excessive driveshaft angle"
- end
-
- table.insert(self.WheelLink,Target)
- table.insert(self.WheelSide,Side)
- if not self.WheelCount[Side] then self.WheelCount[Side] = 0 end
- self.WheelCount[Side] = self.WheelCount[Side] + 1
- table.insert(self.WheelAxis,Target:WorldToLocal(self.Entity:GetRight()+TargetPos))
-
- local RopeL = ( self.Entity:LocalToWorld(LinkPos)-TargetPos ):Length()
- constraint.Rope( self.Entity, Target, 0, 0, LinkPos, Target:WorldToLocal(TargetPos), RopeL, RopeL*0.2, 0, 1, "cable/cable2", false )
- table.insert( self.WheelRopeL,RopeL )
- table.insert( self.WheelOutput,LinkPos )
-
- return false
-
-end
-
-function ENT:Unlink( Target )
-
- for Key,Value in pairs(self.WheelLink) do
- if Value == Target then
-
- local Constraints = constraint.FindConstraints(Value, "Rope")
- if Constraints then
- for Key,Rope in pairs(Constraints) do
- if Rope.Ent1 == self.Entity or Rope.Ent2 == self.Entity then
- Rope.Constraint:Remove()
- end
- end
- end
-
- if not self.WheelCount[self.WheelSide[Key]] then self.WheelCount[self.WheelSide[Key]] = 0 end
- self.WheelCount[self.WheelSide[Key]] = math.max(self.WheelCount[self.WheelSide[Key]] - 1,0)
-
- table.remove(self.WheelLink,Key)
- table.remove(self.WheelAxis,Key)
- table.remove(self.WheelSide,Key)
- table.remove(self.WheelRopeL,Key)
- table.remove(self.WheelOutput,Key)
- return false
- end
- end
-
- return "Didn't find the wheel to unlink"
-
-end
-
-//Duplicator stuff
-
-function ENT:PreEntityCopy()
-
- //Link Saving
- local info = {}
- local entids = {}
- for Key, Value in pairs(self.WheelLink) do --Clean the table of any invalid entities
- if not Value:IsValid() then
- table.remove(self.WheelLink, Key)
- end
- end
- for Key, Value in pairs(self.WheelLink) do --Then save it
- table.insert(entids, Value:EntIndex())
- end
-
- info.entities = entids
- if info.entities then
- duplicator.StoreEntityModifier( self.Entity, "WheelLink", info )
- end
-
- //Wire dupe info
- local DupeInfo = WireLib.BuildDupeInfo(self.Entity)
- if(DupeInfo) then
- duplicator.StoreEntityModifier(self.Entity,"WireDupeInfo",DupeInfo)
- end
-
-end
-
-function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
-
- //Link Pasting
- if (Ent.EntityMods) and (Ent.EntityMods.WheelLink) and (Ent.EntityMods.WheelLink.entities) then
- local WheelLink = Ent.EntityMods.WheelLink
- if WheelLink.entities and table.Count(WheelLink.entities) > 0 then
- for _,ID in pairs(WheelLink.entities) do
- local Linked = CreatedEntities[ ID ]
- if Linked and Linked:IsValid() then
- self:Link( Linked )
- end
- end
- end
- Ent.EntityMods.WheelLink = nil
- end
-
- //Wire dupe info
- if(Ent.EntityMods and Ent.EntityMods.WireDupeInfo) then
- WireLib.ApplyDupeInfo(Player, Ent, Ent.EntityMods.WireDupeInfo, function(id) return CreatedEntities[id] end)
- end
-
-end
-
-function ENT:OnRemove()
-
- for Key,Value in pairs(self.Master) do --Let's unlink ourselves from the engines properly
- if self.Master[Key] and self.Master[Key]:IsValid() then
- self.Master[Key]:Unlink( self.Entity )
- end
- end
-
- Wire_Remove(self.Entity)
-end
-
-function ENT:OnRestore()
- Wire_Restored(self.Entity)
-end
-
-
diff --git a/lua/entities/ACF_Gearbox/shared.lua b/lua/entities/ACF_Gearbox/shared.lua
deleted file mode 100644
index 306dc3679..000000000
--- a/lua/entities/ACF_Gearbox/shared.lua
+++ /dev/null
@@ -1,9 +0,0 @@
-ENT.Type = "anim"
-ENT.Base = "base_gmodentity"
-ENT.Author = "Kafouille"
-
-ENT.Spawnable = false
-ENT.AdminSpawnable = false
-
-
-
diff --git a/lua/entities/ACF_Gun/cl_init.lua b/lua/entities/ACF_Gun/cl_init.lua
deleted file mode 100644
index 31fa6c45c..000000000
--- a/lua/entities/ACF_Gun/cl_init.lua
+++ /dev/null
@@ -1,96 +0,0 @@
-include("shared.lua")
-
-ENT.RenderGroup = RENDERGROUP_OPAQUE
-
-ENT.AutomaticFrameAdvance = true
-
-function ENT:Draw()
- self:DoNormalDraw()
- self:DrawModel()
- Wire_Render(self.Entity)
-end
-
-function ENT:Initialize()
-
- self.LastFire = 0
- self.Reload = 1
- self.CloseTime = 1
- self.Rate = 1
- self.RateScale = 1
- self.FireAnim = self:LookupSequence( "shoot" )
- self.CloseAnim = self:LookupSequence( "load" )
-
-end
-
-function ENT:DoNormalDraw()
- local e = self.Entity
- if (LocalPlayer():GetEyeTrace().Entity == e and EyePos():Distance(e:GetPos()) < 256) then
- if(self:GetOverlayText() ~= "") then
- AddWorldTip(e:EntIndex(),self:GetOverlayText(),0.5,e:GetPos(),e)
- end
- end
-end
-
-function ENT:Think()
- if (CurTime() >= (self.NextRBUpdate or 0)) then
- self.NextRBUpdate = CurTime() + math.random(30,100)/10 --update renderbounds every 3 to 10 seconds
- Wire_UpdateRenderBounds(self.Entity)
- end
-
- local SinceFire = (CurTime() - self.LastFire)
- self:SetCycle( SinceFire*self.Rate/self.RateScale )
- if CurTime() > self.LastFire + self.CloseTime and self.CloseAnim then
- self:ResetSequence( self.CloseAnim )
- self:SetCycle( (SinceFire - self.CloseTime)*self.Rate/self.RateScale )
- self.Rate = 1/(self.Reload - self.CloseTime) --Base anim time is 1s, rate is in 1/10 of a second
- self:SetPlaybackRate( self.Rate )
- end
-
- self.Entity:NextThink(CurTime())
- return true
-end
-
-function ENT:Animate( Class, ReloadTime, LoadOnly )
-
- if self.CloseAnim and self.CloseAnim > 0 then
- self.CloseTime = math.max(ReloadTime-0.75,ReloadTime*0.75)
- else
- self.CloseTime = ReloadTime
- self.CloseAnim = nil
- end
-
- self:ResetSequence( self.FireAnim )
- self:SetCycle( 0 )
- self.RateScale = self:SequenceDuration()
- if LoadOnly then
- self.Rate = 1000000
- else
- self.Rate = 1/math.Clamp(self.CloseTime,0.1,1.5) --Base anim time is 1s, rate is in 1/10 of a second
- end
- self:SetPlaybackRate( self.Rate )
- self.LastFire = CurTime()
- self.Reload = ReloadTime
-
-end
-
-function ACFGunGUICreate( Table )
-
- acfmenupanel:CPanelText("Name", Table.name)
-
- acfmenupanel.CData.DisplayModel = vgui.Create( "DModelPanel", acfmenupanel.CustomDisplay )
- acfmenupanel.CData.DisplayModel:SetModel( Table.model )
- acfmenupanel.CData.DisplayModel:SetCamPos( Vector( 250 , 500 , 250 ) )
- acfmenupanel.CData.DisplayModel:SetLookAt( Vector( 0, 0, 0 ) )
- acfmenupanel.CData.DisplayModel:SetFOV( 20 )
- acfmenupanel.CData.DisplayModel:SetSize(acfmenupanel:GetWide(),acfmenupanel:GetWide())
- acfmenupanel.CData.DisplayModel.LayoutEntity = function( panel , entity ) end
- acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.DisplayModel )
-
- acfmenupanel:CPanelText("Desc", Table.desc)
- acfmenupanel:CPanelText("Caliber", "Caliber : "..(Table.caliber*10).."mm")
- acfmenupanel:CPanelText("Weight", "Weight : "..Table.weight.."kg")
-
- acfmenupanel.CustomDisplay:PerformLayout()
-
-end
-
diff --git a/lua/entities/ACF_Gun/init.lua b/lua/entities/ACF_Gun/init.lua
deleted file mode 100644
index 1c4ef12f6..000000000
--- a/lua/entities/ACF_Gun/init.lua
+++ /dev/null
@@ -1,513 +0,0 @@
-AddCSLuaFile( "shared.lua" )
-AddCSLuaFile( "cl_init.lua" )
-
-include('shared.lua')
-
-function ENT:Initialize()
-
- self.ReloadTime = 1
- self.Ready = true
- self.Firing = nil
- self.Reloading = nil
- self.NextFire = 0
- self.LastSend = 0
- self.Owner = self.Entity
-
- self.IsMaster = true
- self.AmmoLink = {}
- self.CurAmmo = 1
- self.Sequence = 1
-
- self.BulletData = {}
- self.BulletData["Type"] = "Empty"
- self.BulletData["PropMass"] = 0
- self.BulletData["ProjMass"] = 0
-
- self.Inaccuracy = 1
-
- self.Inputs = Wire_CreateInputs( self.Entity, { "Fire", "Unload", "Reload" } )
- self.Outputs = WireLib.CreateSpecialOutputs( self.Entity, { "Ready", "AmmoCount", "Entity", "Shots Left" }, { "NORMAL" , "NORMAL" , "ENTITY", "NORMAL" } )
- Wire_TriggerOutput(self.Entity, "Entity", self.Entity)
- self.WireDebugName = "ACF Gun"
-
-end
-
-function MakeACF_Gun(Owner, Pos, Angle, Id)
-
- if not Owner:CheckLimit("_acf_gun") then return false end
-
- local Gun = ents.Create("ACF_Gun")
- local List = list.Get("ACFEnts")
- local Classes = list.Get("ACFClasses")
- if not Gun:IsValid() then return false end
- Gun:SetAngles(Angle)
- Gun:SetPos(Pos)
- Gun:Spawn()
-
- Gun:SetPlayer(Owner)
- Gun.Owner = Owner
- Gun.Id = Id
- Gun.Caliber = List["Guns"][Id]["caliber"]
- Gun.Model = List["Guns"][Id]["model"]
- Gun.Mass = List["Guns"][Id]["weight"]
- Gun.Class = List["Guns"][Id]["gunclass"]
- -- Custom BS for karbine. Per Gun ROF.
- Gun.PGRoFmod = 1
- if(List["Guns"][Id]["rofmod"]) then
- Gun.PGRoFmod = math.max(0, List["Guns"][Id]["rofmod"])
- end
- -- Custom BS for karbine. Magazine Size, Mag reload Time
- Gun.CurrentShot = 0
- Gun.MagSize = 1
- if(List["Guns"][Id]["magsize"]) then
- Gun.MagSize = math.max(Gun.MagSize, List["Guns"][Id]["magsize"])
- end
- Gun.MagReload = 0
- if(List["Guns"][Id]["magreload"]) then
- Gun.MagReload = math.max(Gun.MagReload, List["Guns"][Id]["magreload"])
- end
- -- self.CurrentShot, self.MagSize, self.MagReload
-
- Gun:SetNWString( "Class" , Gun.Class )
- Gun.Muzzleflash = Classes["GunClass"][Gun.Class]["muzzleflash"]
- Gun.RoFmod = Classes["GunClass"][Gun.Class]["rofmod"]
- Gun.Sound = Classes["GunClass"][Gun.Class]["sound"]
- Gun.Inaccuracy = Classes["GunClass"][Gun.Class]["spread"]
- Gun:SetModel( Gun.Model )
-
- Gun:PhysicsInit( SOLID_VPHYSICS )
- Gun:SetMoveType( MOVETYPE_VPHYSICS )
- Gun:SetSolid( SOLID_VPHYSICS )
-
- local Muzzle = Gun:GetAttachment( Gun:LookupAttachment( "muzzle" ) )
- Gun.Muzzle = Gun:WorldToLocal(Muzzle.Pos)
-
- /*local Height = 30 --Damn you Garry
- local Width = 30
- local length = 105
- local Scale = Gun.Caliber/30
- local VertexFile = file.Read(Gun.Class..".txt", "DATA")
- local PerVertex = string.Explode( "v", VertexFile )
- local Import = {}
- for Key, Value in pairs(PerVertex) do
- local Table = string.Explode( " ", Value )
- local Vec = Vector(tonumber(Table[2],10),tonumber(Table[4],10),tonumber(Table[3],10))
- if Vec != Vector(1,1,1) then
- table.insert(Import, Vertex( Vec*Scale,0,0 ) )
- end
- end
- PrintTable(Import)
- Gun:SetNWFloat( "Scale" , Scale )
-
- local p1 = Vector(length/-2*Scale,Width/-2*Scale,Height/-2*Scale)
- local p2 = Vector(length/-2*Scale,Width/2*Scale,Height/-2*Scale)
- local p3 = Vector(length/2*Scale,Width/2*Scale,Height/-2*Scale)
- local p4 = Vector(length/2*Scale,Width/-2*Scale,Height/-2*Scale)
- local p5 = Vector(length/-2*Scale,Width/-2*Scale,Height/2*Scale)
- local p6 = Vector(length/-2*Scale,Width/2*Scale,Height/2*Scale)
- local p7 = Vector(length/2*Scale,Width/2*Scale,Height/2*Scale)
- local p8 = Vector(length/2*Scale,Width/-2*Scale,Height/2*Scale)
-
- local Vertices = {}
- table.Add( Vertices, MeshQuad( p5, p6, p7, p8, 0 ) )
- table.Add( Vertices, MeshQuad( p4, p3, p2, p1, 0 ) )
- table.Add( Vertices, MeshQuad( p8, p7, p3, p4, 0 ) )
- table.Add( Vertices, MeshQuad( p6, p5, p1, p2, 0 ) )
- table.Add( Vertices, MeshQuad( p5, p8, p4, p1, 0 ) )
- table.Add( Vertices, MeshQuad( p7, p6, p2, p3, 0 ) )
-
- PrintTable(Vertices)
- Gun:PhysicsFromMesh( Import )*/
-
- local phys = Gun:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:SetMass( Gun.Mass )
- end
-
- undo.Create("ACF Gun")
- undo.AddEntity( Gun )
- undo.SetPlayer( Owner )
- undo.Finish()
-
- Owner:AddCount("_acf_gun", Gun)
- Owner:AddCleanup( "acfmenu", Gun )
-
- return Gun
-end
-list.Set( "ACFCvars", "acf_gun" , {"id"} )
-duplicator.RegisterEntityClass("acf_gun", MakeACF_Gun, "Pos", "Angle", "Id")
-
-function ENT:Link( Target )
-
- if ( !Target or Target:GetClass() != "acf_ammo" ) then return ("Only accepts ammo crates") end
- if ( Target.BulletData["Id"] != self.Entity.Id ) then return ("Wrong ammo type") end
- if ( Target.BulletData["RoundType"] == "Refill" ) then return ("Refill crates cannot be linked") end
-
- table.insert(self.AmmoLink,Target)
- table.insert(Target.Master,self.Entity)
-
- if ( self.BulletData["Type"] == "Empty" and Target["Load"] ) then
- self:UnloadAmmo()
- end
-
- return false
-
-end
-
-function ENT:Unlink( Target )
-
- local Success = false
- for Key,Value in pairs(self.AmmoLink) do
- if Value == Target then
- table.remove(self.AmmoLink,Key)
- Success = true
- end
- end
-
- if Success then
- return false
- else
- return "Didn't find the crate to unlink"
- end
-
-end
-
-function ENT:TriggerInput( iname , value )
-
- if (iname == "Unload" and value > 0) then
- timer.Simple( 0, self.UnloadAmmo() )
- elseif ( iname == "Fire" and value > 0 ) then
- if self.Entity.NextFire < CurTime() then
- self.Entity:FireShell()
- self.Entity:Think()
- end
- self.Firing = true
- elseif ( iname == "Fire" and value <= 0 ) then
- self.Firing = false
- elseif ( iname == "Reload" and value > 0 ) then
- self.Reloading = true
- elseif ( iname == "Reload" and value <= 0 ) then
- self.Reloading = false
- end
-end
-
-function RetDist( enta, entb )
- if not ((enta and enta:IsValid()) or (entb and entb:IsValid())) then return 0 end
- disp = enta:GetPos() - entb:GetPos()
- dist = math.sqrt( disp.x * disp.x + disp.y * disp.y + disp.z * disp.z )
- return dist
-end
-
-function ENT:Think()
-
- local Time = CurTime()
- if self.LastSend+1 <= Time then
- local Ammo = 0
- for Key,AmmoEnt in pairs(self.AmmoLink) do
- if AmmoEnt and AmmoEnt:IsValid() and AmmoEnt["Load"] then
- if RetDist( self, AmmoEnt ) < 512 then
- Ammo = Ammo + (AmmoEnt.Ammo or 0)
- else
- self:Unlink( AmmoEnt )
- soundstr = "physics/metal/metal_box_impact_bullet" .. tostring(math.random(1, 3)) .. ".wav"
- self:EmitSound(soundstr,500,100)
- end
- end
- end
- Wire_TriggerOutput(self.Entity, "AmmoCount", Ammo)
- if( self.MagSize ) then
- Wire_TriggerOutput(self.Entity, "Shots Left", self.MagSize - self.CurrentShot)
- else
- Wire_TriggerOutput(self.Entity, "Shots Left", 1)
- end
-
- self.Entity:SetNetworkedBeamString("GunType",self.Entity.Id)
- self.Entity:SetNetworkedBeamInt("Ammo",Ammo)
- self.Entity:SetNetworkedBeamString("Type",self.BulletData["Type"])
- self.Entity:SetNetworkedBeamInt("Mass",self.BulletData["ProjMass"]*100)
- self.Entity:SetNetworkedBeamInt("Propellant",self.BulletData["PropMass"]*1000)
-
- self.LastSend = Time
-
- end
-
- if self.NextFire <= Time then
- self.Ready = true
- Wire_TriggerOutput(self.Entity, "Ready", 1)
- if self.Firing then
- self:FireShell()
- elseif self.Reloading then
- self:ReloadMag()
- end
- end
-
- self.Entity:NextThink(Time)
- return true
-
-end
-
-function ENT:CheckWeight()
- local mass = self.Entity:GetPhysicsObject():GetMass()
- local maxmass = GetConVarNumber("bnk_maxweight") * 1000 + 999
-
- local chk = false
-
- local allents = constraint.GetAllConstrainedEntities( self.Entity )
- for _, ent in pairs(allents) do
- if (ent and ent:IsValid() and not ent:IsPlayer() and not (ent == self)) then
- local phys = ent:GetPhysicsObject()
- if(phys:IsValid()) then
- mass = mass + phys:GetMass()
- end
- end
- end
-
- if( mass < maxmass ) then
- chk = true
- end
-
- return chk
-end
-
-function ENT:ReloadMag()
- if(self.IsUnderWeight == nil) then
- self.IsUnderWeight = true
- if(ISBNK) then
- self.IsUnderWeight = self:CheckWeight()
- end
- end
- if ( (self.CurrentShot > 0) and self.IsUnderWeight and self.Ready and self.Entity:GetPhysicsObject():GetMass() >= self.Mass and not self.Entity:GetParent():IsValid() ) then
- if ( ACF.RoundTypes[self.BulletData["Type"]] ) then --Check if the roundtype loaded actually exists
- self:LoadAmmo(self.MagReload, false)
- self:EmitSound("weapons/357/357_reload4.wav",500,100)
- self.CurrentShot = 0
- Wire_TriggerOutput(self.Entity, "Ready", 0)
- else
- self.CurrentShot = 0
- self.Ready = false
- Wire_TriggerOutput(self.Entity, "Ready", 0)
- self:LoadAmmo(false, true)
- end
- end
-end
-
-function ENT:FireShell()
- if(self.IsUnderWeight == nil) then
- self.IsUnderWeight = true
- if(ISBNK) then
- self.IsUnderWeight = self:CheckWeight()
- end
- end
-
- local bool = true
- if(ISSITP) then
- if(self.sitp_spacetype != "space" and self.sitp_spacetype != "planet") then
- bool = false
- end
- if(self.sitp_core == false) then
- bool = false
- end
- end
- if ( bool and self.IsUnderWeight and self.Ready and self.Entity:GetPhysicsObject():GetMass() >= self.Mass and not self.Entity:GetParent():IsValid() ) then
- Blacklist = {}
- if not ACF.AmmoBlacklist[self.BulletData["Type"]] then
- Blacklist = {}
- else
- Blacklist = ACF.AmmoBlacklist[self.BulletData["Type"]]
- end
- if ( ACF.RoundTypes[self.BulletData["Type"]] and !table.HasValue( Blacklist, self.Class ) ) then --Check if the roundtype loaded actually exists
-
- local MuzzlePos = self:LocalToWorld(self.Muzzle)
- local MuzzleVec = self:GetForward()
- local Inaccuracy = VectorRand() / 360 * self.Inaccuracy
-
- self:MuzzleEffect( MuzzlePos , MuzzleVec )
-
- self.BulletData["Pos"] = MuzzlePos
- self.BulletData["Flight"] = (MuzzleVec+Inaccuracy):GetNormalized() * self.BulletData["MuzzleVel"] * 39.37 + self:GetVelocity()
- self.BulletData["Owner"] = self.Owner
- self.BulletData["Gun"] = self.Entity
- self.CreateShell = ACF.RoundTypes[self.BulletData["Type"]]["create"]
- self:CreateShell( self.BulletData )
-
- local Gun = self.Entity:GetPhysicsObject()
- if (Gun:IsValid()) then
- Gun:ApplyForceCenter( self:GetForward() * -(self.BulletData["ProjMass"] * self.BulletData["MuzzleVel"] * 39.37 + self.BulletData["PropMass"] * 3000 * 39.37))
- end
-
- self.Ready = false
- self.CurrentShot = math.min(self.CurrentShot + 1, self.MagSize)
- if((self.CurrentShot >= self.MagSize) and (self.MagSize > 1)) then
- self:LoadAmmo(self.MagReload, false)
- self:EmitSound("weapons/357/357_reload4.wav",500,100)
- self.CurrentShot = 0
- else
- self:LoadAmmo(false, false)
- end
- Wire_TriggerOutput(self.Entity, "Ready", 0)
- else
- self.CurrentShot = 0
- self.Ready = false
- Wire_TriggerOutput(self.Entity, "Ready", 0)
- self:LoadAmmo(false, true)
- end
- end
-
-end
-
-function ENT:CreateShell()
- --You overwrite this with your own function, defined in the ammo definition file
-end
-
-function ENT:FindNextCrate()
-
- local MaxAmmo = table.getn(self.AmmoLink)
- local AmmoEnt = nil
- local i = 0
-
- while i <= MaxAmmo and not (AmmoEnt and AmmoEnt:IsValid() and AmmoEnt.Ammo > 0) do
-
- self.CurAmmo = self.CurAmmo + 1
- if self.CurAmmo > MaxAmmo then self.CurAmmo = 1 end
-
- AmmoEnt = self.AmmoLink[self.CurAmmo]
- if AmmoEnt and AmmoEnt:IsValid() and AmmoEnt.Ammo > 0 and AmmoEnt["Load"] then
- return AmmoEnt
- end
- AmmoEnt = nil
-
- i = i + 1
- end
-
- return false
-end
-
-function ENT:LoadAmmo( AddTime, Reload )
-
- local AmmoEnt = self:FindNextCrate()
-
- if AmmoEnt then
- AmmoEnt.Ammo = AmmoEnt.Ammo - 1
- self.BulletData = AmmoEnt.BulletData
- self.BulletData["Crate"] = AmmoEnt:EntIndex()
-
- self.ReloadTime = ((self.BulletData["RoundVolume"]/500)^0.60)*self.RoFmod*self.PGRoFmod
- Wire_TriggerOutput(self.Entity, "Loaded", self.BulletData["Type"])
-
- self.NextFire = CurTime() + self.ReloadTime
- if AddTime then
- self.NextFire = CurTime() + self.ReloadTime + AddTime
- end
- if Reload then
- self:ReloadEffect()
- end
- self.Entity:Think()
- return true
- else
- self.BulletData = {}
- self.BulletData["Type"] = "Empty"
- self.BulletData["PropMass"] = 0
- self.BulletData["ProjMass"] = 0
-
- self:EmitSound("weapons/pistol/pistol_empty.wav",500,100)
- Wire_TriggerOutput(self.Entity, "Loaded", "Empty")
-
- self.NextFire = CurTime()+0.5
- self.Entity:Think()
- end
- return false
-
-end
-
-function ENT:UnloadAmmo()
-
- local Crate = Entity( self.BulletData["Crate"] )
- if Crate and Crate:IsValid() and self.BulletData["Type"] == Crate.BulletData["Type"] then
- Crate.Ammo = Crate.Ammo+1
- end
-
- self.Ready = false
- Wire_TriggerOutput(self.Entity, "Ready", 0)
- self:LoadAmmo( math.min(self.ReloadTime,math.max(self.ReloadTime - (self.NextFire - CurTime()),0) ) , true )
- self:EmitSound("weapons/357/357_reload4.wav",500,100)
-
-end
-
-function ENT:MuzzleEffect()
-
- local Effect = EffectData()
- Effect:SetEntity( self.Entity )
- Effect:SetScale( self.BulletData["PropMass"] )
- Effect:SetMagnitude( self.ReloadTime )
- Effect:SetSurfaceProp( ACF.RoundTypes[self.BulletData["Type"]]["netid"] ) --Encoding the ammo type into a table index
- util.Effect( "ACF_MuzzleFlash", Effect, true, true )
-
-end
-
-function ENT:ReloadEffect()
-
- local Effect = EffectData()
- Effect:SetEntity( self.Entity )
- Effect:SetScale( 0 )
- Effect:SetMagnitude( self.ReloadTime )
- Effect:SetSurfaceProp( ACF.RoundTypes[self.BulletData["Type"]]["netid"] ) --Encoding the ammo type into a table index
- util.Effect( "ACF_MuzzleFlash", Effect, true, true )
-
-end
-
-function ENT:PreEntityCopy()
-
- local info = {}
- local entids = {}
- for Key, Value in pairs(self.AmmoLink) do --First clean the table of any invalid entities
- if not Value:IsValid() then
- table.remove(self.AmmoLink, Value)
- end
- end
- for Key, Value in pairs(self.AmmoLink) do --Then save it
- table.insert(entids, Value:EntIndex())
- end
- info.entities = entids
- if info.entities then
- duplicator.StoreEntityModifier( self.Entity, "ACFAmmoLink", info )
- end
-
- //Wire dupe info
- local DupeInfo = WireLib.BuildDupeInfo(self.Entity)
- if(DupeInfo) then
- duplicator.StoreEntityModifier(self.Entity,"WireDupeInfo",DupeInfo)
- end
-
-end
-
-function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
-
- if (Ent.EntityMods) and (Ent.EntityMods.ACFAmmoLink) and (Ent.EntityMods.ACFAmmoLink.entities) then
- local AmmoLink = Ent.EntityMods.ACFAmmoLink
- if AmmoLink.entities and table.Count(AmmoLink.entities) > 0 then
- for _,AmmoID in pairs(AmmoLink.entities) do
- local Ammo = CreatedEntities[ AmmoID ]
- if Ammo and Ammo:IsValid() then
- self:Link( Ammo )
- end
- end
- end
- Ent.EntityMods.ACFAmmoLink = nil
- end
-
- //Wire dupe info
- if(Ent.EntityMods and Ent.EntityMods.WireDupeInfo) then
- WireLib.ApplyDupeInfo(Player, Ent, Ent.EntityMods.WireDupeInfo, function(id) return CreatedEntities[id] end)
- end
-
-end
-
-function ENT:OnRemove()
- Wire_Remove(self.Entity)
-end
-
-function ENT:OnRestore()
- Wire_Restored(self.Entity)
-end
-
-
diff --git a/lua/entities/ACF_Gun/shared.lua b/lua/entities/ACF_Gun/shared.lua
deleted file mode 100644
index 58617e15e..000000000
--- a/lua/entities/ACF_Gun/shared.lua
+++ /dev/null
@@ -1,30 +0,0 @@
-ENT.Type = "anim"
-ENT.Base = "base_gmodentity"
-ENT.Author = "Kafouille"
-
-ENT.Spawnable = false
-ENT.AdminSpawnable = false
-
-function ENT:GetOverlayText()
- local name = self.Entity:GetNetworkedString("WireName")
- local GunType = self.Entity:GetNetworkedBeamString("GunType")
- local Ammo = self.Entity:GetNetworkedBeamInt("Ammo")
- local RoundType = self.Entity:GetNetworkedBeamString("Type")
- local Mass = self.Entity:GetNetworkedBeamInt("Mass")/100
- local Filler =self.Entity:GetNetworkedBeamInt("Filler")/100
- local Propellant = self.Entity:GetNetworkedBeamInt("Propellant")/1000
- local txt = GunType.." : "..Ammo.." : \nRound Type : "..RoundType.."\nRound Mass : "..Mass.."\nFiller Mass : "..Filler.."\nPropellant : "..Propellant or ""
- if (not game.SinglePlayer()) then
- local PlayerName = self:GetPlayerName()
- txt = txt .. "\n(" .. PlayerName .. ")"
- end
- if(name and name ~= "") then
- if (txt == "") then
- return "- "..name.." -"
- end
- return "- "..name.." -\n"..txt
- end
- return txt
-end
-
-
diff --git a/lua/entities/ACF_Rack/cl_init.lua b/lua/entities/ACF_Rack/cl_init.lua
deleted file mode 100644
index 8286eb233..000000000
--- a/lua/entities/ACF_Rack/cl_init.lua
+++ /dev/null
@@ -1 +0,0 @@
--- cl_init.lua
\ No newline at end of file
diff --git a/lua/entities/ACF_Rack/init.lua b/lua/entities/ACF_Rack/init.lua
deleted file mode 100644
index d50de2bdd..000000000
--- a/lua/entities/ACF_Rack/init.lua
+++ /dev/null
@@ -1,73 +0,0 @@
--- init.lua
-
-AddCSLuaFile( "shared.lua" )
-AddCSLuaFile( "cl_init.lua" )
-
-include('shared.lua')
-
-function ENT:Initialize()
- self.HasFired = false
- self.Firing = false
-end
-
-function ENT:Think()
-
-end
-
-function MakeACF_Rack (Owner, Pos, Angle, Id)
-
-end
-
-list.Set( "ACFCvars", "acf_rack" , {"id"} )
-duplicator.RegisterEntityClass("acf_rack", MakeACF_Rack, "Pos", "Angle", "Id")
-
-function ENT:TriggerInput( iname , value )
-
- if ( iname == "Fire" and value > 0 ) then
- if self.HasFired == false then
- self.Entity:FireMissile()
- self.Entity:Think()
- end
- self.Firing = true
- elseif ( iname == "Fire" and value <= 0 ) then
- self.HasFired = false
- self.Firing = false
- end
-end
-
-function ENT:Think()
-end
-
-function ENT:FireMissile()
-end
-
-function ENT:MuzzleEffect()
-
-end
-
-function ENT:PreEntityCopy()
-
- //Wire dupe info
- local DupeInfo = WireLib.BuildDupeInfo(self.Entity)
- if(DupeInfo) then
- duplicator.StoreEntityModifier(self.Entity,"WireDupeInfo",DupeInfo)
- end
-
-end
-
-function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
-
- //Wire dupe info
- if(Ent.EntityMods and Ent.EntityMods.WireDupeInfo) then
- WireLib.ApplyDupeInfo(Player, Ent, Ent.EntityMods.WireDupeInfo, function(id) return CreatedEntities[id] end)
- end
-
-end
-
-function ENT:OnRemove()
- Wire_Remove(self.Entity)
-end
-
-function ENT:OnRestore()
- Wire_Restored(self.Entity)
-end
\ No newline at end of file
diff --git a/lua/entities/ACF_Rack/shared.lua b/lua/entities/ACF_Rack/shared.lua
deleted file mode 100644
index fcf89a00f..000000000
--- a/lua/entities/ACF_Rack/shared.lua
+++ /dev/null
@@ -1,8 +0,0 @@
--- shared.lua
-
-ENT.Type = "anim"
-ENT.Base = "base_gmodentity"
-ENT.Author = "Sestze"
-
-ENT.Spawnable = false
-ENT.AdminSpawnable = false
\ No newline at end of file
diff --git a/lua/entities/Debris/cl_init.lua b/lua/entities/Debris/cl_init.lua
deleted file mode 100644
index eacca46db..000000000
--- a/lua/entities/Debris/cl_init.lua
+++ /dev/null
@@ -1,11 +0,0 @@
- include('shared.lua')
- //[[---------------------------------------------------------
- //Name: Draw Purpose: Draw the model in-game.
- //Remember, the things you render first will be underneath!
- //-------------------------------------------------------]]
- function ENT:Draw()
- // self.BaseClass.Draw(self)
- -- We want to override rendering, so don't call baseclass.
- // Use this when you need to add to the rendering.
- self.Entity:DrawModel() // Draw the model.
- end
\ No newline at end of file
diff --git a/lua/entities/Debris/init.lua b/lua/entities/Debris/init.lua
deleted file mode 100644
index 25776e223..000000000
--- a/lua/entities/Debris/init.lua
+++ /dev/null
@@ -1,38 +0,0 @@
-AddCSLuaFile( "cl_init.lua" )
-AddCSLuaFile( "shared.lua" )
-
-include('shared.lua')
-
-
-function ENT:Initialize()
-
- self.Timer = CurTime() + 60
- self.Entity:PhysicsInit( SOLID_VPHYSICS )
- self.Entity:SetMoveType( MOVETYPE_VPHYSICS )
- self.Entity:SetSolid( SOLID_VPHYSICS )
- self.Entity:SetCollisionGroup( COLLISION_GROUP_WORLD )
- local phys = self.Entity:GetPhysicsObject()
- if (phys:IsValid()) then
- phys:Wake()
- end
-
-end
-
-function ENT:Think()
-
- if (self.Timer < CurTime()) then
- self.Entity:Remove()
- end
-
- self.Entity:NextThink( CurTime() + 60)
-
- return true
-
-end
-
-function ENT:OnTakeDamage( dmginfo )
-
- // React physically when shot/getting blown
- self.Entity:TakePhysicsDamage( dmginfo )
-
-end
diff --git a/lua/entities/Debris/shared.lua b/lua/entities/Debris/shared.lua
deleted file mode 100644
index 6219f18d7..000000000
--- a/lua/entities/Debris/shared.lua
+++ /dev/null
@@ -1,11 +0,0 @@
- ENT.Type = "anim"
- ENT.Base = "base_gmodentity"
- ENT.PrintName = "Debris"
- ENT.Author = "Kafouille"
- ENT.Contact = "Kafouille@gmail.com"
- ENT.Purpose = "Atmospheric"
- ENT.Instructions = "A clone of props killed during battle"
-
-ENT.Spawnable = false
-ENT.AdminSpawnable = false
-
diff --git a/lua/entities/acf_ammo.lua b/lua/entities/acf_ammo.lua
new file mode 100644
index 000000000..0a1c34cbf
--- /dev/null
+++ b/lua/entities/acf_ammo.lua
@@ -0,0 +1,617 @@
+
+AddCSLuaFile()
+
+DEFINE_BASECLASS( "base_wire_entity" )
+
+ENT.PrintName = "ACF Ammo Crate"
+ENT.WireDebugName = "ACF Ammo Crate"
+
+if CLIENT then
+
+ --Shamefully stolen from lua rollercoaster. I'M SO SORRY. I HAD TO.
+
+ local function Bezier( a, b, c, d, t )
+ local ab,bc,cd,abbc,bccd
+
+ ab = LerpVector(t, a, b)
+ bc = LerpVector(t, b, c)
+ cd = LerpVector(t, c, d)
+ abbc = LerpVector(t, ab, bc)
+ bccd = LerpVector(t, bc, cd)
+ dest = LerpVector(t, abbc, bccd)
+
+ return dest
+ end
+
+
+ local function BezPoint(perc, Table)
+ perc = perc or self.Perc
+
+ local vec = Vector(0, 0, 0)
+
+ vec = Bezier(Table[1], Table[2], Table[3], Table[4], perc)
+
+ return vec
+ end
+
+ function ACF_DrawRefillAmmo( Table )
+
+ for k,v in pairs( Table ) do
+ local St, En = v.EntFrom:LocalToWorld(v.EntFrom:OBBCenter()), v.EntTo:LocalToWorld(v.EntTo:OBBCenter())
+ local Distance = (En - St):Length()
+ local Amount = math.Clamp((Distance/50),2,100)
+ local Time = (SysTime() - v.StTime)
+ local En2, St2 = En + Vector(0,0,100), St + ((En-St):GetNormalized() * 10)
+ local vectab = { St, St2, En2, En}
+ local center = (St+En)/2
+ for I = 1, Amount do
+ local point = BezPoint(((((I+Time)%Amount))/Amount), vectab)
+ local ang = (point - center):Angle()
+ local MdlTbl = {
+ model = v.Model,
+ pos = point,
+ angle = ang
+ }
+ render.Model( MdlTbl )
+ end
+ end
+
+ end
+
+ function ACF_TrimInvalidRefillEffects(effectsTbl)
+
+ local effect
+
+ for i=1, #effectsTbl do
+ effect = effectsTbl[i]
+
+ if not (IsValid(effect.EntFrom) and IsValid(effect.EntTo)) then
+ effectsTbl[i] = nil
+ end
+ end
+
+ end
+
+ local ACF_AmmoInfoWhileSeated = CreateClientConVar("ACF_AmmoInfoWhileSeated", 0, true, false)
+
+ function ENT:Draw()
+
+ local lply = LocalPlayer()
+ local hideBubble = not GetConVar("ACF_AmmoInfoWhileSeated"):GetBool() and IsValid(lply) and lply:InVehicle()
+
+ self.BaseClass.DoNormalDraw(self, false, hideBubble)
+ Wire_Render(self)
+
+ if self.GetBeamLength and (not self.GetShowBeam or self:GetShowBeam()) then
+ -- Every SENT that has GetBeamLength should draw a tracer. Some of them have the GetShowBeam boolean
+ Wire_DrawTracerBeam( self, 1, self.GetBeamHighlight and self:GetBeamHighlight() or false )
+ end
+ --self.BaseClass.Draw( self )
+
+ if self.RefillAmmoEffect then
+ ACF_TrimInvalidRefillEffects(self.RefillAmmoEffect)
+ ACF_DrawRefillAmmo( self.RefillAmmoEffect )
+ end
+
+ end
+
+ usermessage.Hook("ACF_RefillEffect", function( msg )
+ local EntFrom, EntTo, Weapon = ents.GetByIndex( msg:ReadFloat() ), ents.GetByIndex( msg:ReadFloat() ), msg:ReadString()
+ if not IsValid( EntFrom ) or not IsValid( EntTo ) then return end
+ //local List = list.Get( "ACFRoundTypes")
+ -- local Mdl = ACF.Weapons.Guns[Weapon].round.model or "models/munitions/round_100mm_shot.mdl"
+ local Mdl = "models/munitions/round_100mm_shot.mdl"
+ EntFrom.RefillAmmoEffect = EntFrom.RefillAmmoEffect or {}
+ table.insert( EntFrom.RefillAmmoEffect, {EntFrom = EntFrom, EntTo = EntTo, Model = Mdl, StTime = SysTime()} )
+ end)
+
+ usermessage.Hook("ACF_StopRefillEffect", function( msg )
+ local EntFrom, EntTo = ents.GetByIndex( msg:ReadFloat() ), ents.GetByIndex( msg:ReadFloat() )
+ //print("stop", EntFrom, EntTo)
+ if not IsValid( EntFrom ) or not IsValid( EntTo )or not EntFrom.RefillAmmoEffect then return end
+ for k,v in pairs( EntFrom.RefillAmmoEffect ) do
+ if v.EntTo == EntTo then
+ if #EntFrom.RefillAmmoEffect<=1 then
+ EntFrom.RefillAmmoEffect = nil
+ return
+ end
+ table.remove(EntFrom.RefillAmmoEffect, k)
+ end
+ end
+ end)
+
+ return
+
+end
+
+function ENT:Initialize()
+
+ self.SpecialHealth = true --If true needs a special ACF_Activate function
+ self.SpecialDamage = true --If true needs a special ACF_OnDamage function
+ self.IsExplosive = true
+ self.Exploding = false
+ self.Damaged = false
+ self.CanUpdate = true
+ self.Load = false
+ self.EmptyMass = 0
+ self.AmmoMassMax = 0
+ self.NextMassUpdate = 0
+ self.Ammo = 0
+ self.NextLegalCheck = ACF.CurTime + 30 -- give any spawning issues time to iron themselves out
+ self.Legal = true
+ self.LegalIssues = ""
+
+ self.Master = {}
+ self.Sequence = 0
+
+ self.Inputs = Wire_CreateInputs( self, { "Active" } ) --, "Fuse Length"
+ self.Outputs = Wire_CreateOutputs( self, { "Munitions", "On Fire" } )
+
+ self.NextThink = CurTime() + 1
+
+ ACF.AmmoCrates = ACF.AmmoCrates or {}
+
+end
+
+function ENT:ACF_Activate( Recalc )
+
+ local EmptyMass = math.max(self.EmptyMass, self:GetPhysicsObject():GetMass() - self.AmmoMassMax)
+
+ self.ACF = self.ACF or {}
+
+ local PhysObj = self:GetPhysicsObject()
+ if not self.ACF.Aera then
+ self.ACF.Aera = PhysObj:GetSurfaceArea() * 6.45
+ end
+ if not self.ACF.Volume then
+ self.ACF.Volume = PhysObj:GetVolume() * 16.38
+ end
+
+ local Armour = EmptyMass*1000 / self.ACF.Aera / 0.78 --So we get the equivalent thickness of that prop in mm if all it's weight was a steel plate
+ local Health = self.ACF.Volume/ACF.Threshold --Setting the threshold of the prop aera gone
+ local Percent = 1
+
+ if Recalc and self.ACF.Health and self.ACF.MaxHealth then
+ Percent = self.ACF.Health/self.ACF.MaxHealth
+ end
+
+ self.ACF.Health = Health * Percent
+ self.ACF.MaxHealth = Health
+ self.ACF.Armour = Armour * (0.5 + Percent/2)
+ self.ACF.MaxArmour = Armour
+ self.ACF.Type = nil
+ self.ACF.Mass = self.Mass
+ self.ACF.Density = (self:GetPhysicsObject():GetMass()*1000) / self.ACF.Volume
+ self.ACF.Type = "Prop"
+
+end
+
+function ENT:ACF_OnDamage( Entity, Energy, FrAera, Angle, Inflictor, Bone, Type ) --This function needs to return HitRes
+
+ local Mul = ((Type == "HEAT" and ACF.HEATMulAmmo) or 1) --Heat penetrators deal bonus damage to ammo
+ local HitRes = ACF_PropDamage( Entity, Energy, FrAera * Mul, Angle, Inflictor ) --Calling the standard damage prop function
+
+ if self.Exploding or not self.IsExplosive then return HitRes end
+
+ if HitRes.Kill then
+ if hook.Run("ACF_AmmoExplode", self, self.BulletData ) == false then return HitRes end
+ self.Exploding = true
+ if( Inflictor and Inflictor:IsValid() and Inflictor:IsPlayer() ) then
+ self.Inflictor = Inflictor
+ end
+ if self.Ammo > 1 then
+ ACF_ScaledExplosion( self )
+ else
+ ACF_HEKill( self, VectorRand() )
+ end
+ end
+
+ -- cookoff chance calculation
+ if self.Damaged then return HitRes end
+ local Ratio = (HitRes.Damage/self.BulletData.RoundVolume)^0.2
+ if ( Ratio * self.Capacity/self.Ammo ) > math.Rand(0,1) then
+ self.Inflictor = Inflictor
+ self.Damaged = CurTime() + (5 - Ratio*3)
+ Wire_TriggerOutput(self, "On Fire", 1)
+ end
+
+ return HitRes --This function needs to return HitRes
+end
+
+function MakeACF_Ammo(Owner, Pos, Angle, Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
+
+ if not Owner:CheckLimit("_acf_ammo") then return false end
+
+ local Ammo = ents.Create("acf_ammo")
+ if not Ammo:IsValid() then return false end
+ Ammo:SetAngles(Angle)
+ Ammo:SetPos(Pos)
+ Ammo:Spawn()
+ Ammo:SetPlayer(Owner)
+ Ammo.Owner = Owner
+
+ Ammo.Model = ACF.Weapons.Ammo[Id].model
+ Ammo:SetModel( Ammo.Model )
+
+ Ammo:PhysicsInit( SOLID_VPHYSICS )
+ Ammo:SetMoveType( MOVETYPE_VPHYSICS )
+ Ammo:SetSolid( SOLID_VPHYSICS )
+
+ Ammo.Id = Id
+ Ammo:CreateAmmo(Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
+
+ Ammo.Ammo = Ammo.Capacity
+ Ammo.EmptyMass = ACF.Weapons.Ammo[Ammo.Id].weight
+ Ammo.Mass = Ammo.EmptyMass + Ammo.AmmoMassMax
+ Ammo.LastMass = 1
+
+ Ammo:UpdateMass()
+
+ Owner:AddCount( "_acf_ammo", Ammo )
+ Owner:AddCleanup( "acfmenu", Ammo )
+
+ table.insert(ACF.AmmoCrates, Ammo)
+
+
+ return Ammo
+end
+list.Set( "ACFCvars", "acf_ammo", {"id", "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9", "data10"} )
+duplicator.RegisterEntityClass("acf_ammo", MakeACF_Ammo, "Pos", "Angle", "Id", "RoundId", "RoundType", "RoundPropellant", "RoundProjectile", "RoundData5", "RoundData6", "RoundData7", "RoundData8", "RoundData9", "RoundData10" )
+
+function ENT:Update( ArgsTable )
+
+ -- That table is the player data, as sorted in the ACFCvars above, with player who shot,
+ -- and pos and angle of the tool trace inserted at the start
+
+ local msg = "Ammo crate updated successfully!"
+
+ if ArgsTable[1] ~= self.Owner then -- Argtable[1] is the player that shot the tool
+ return false, "You don't own that ammo crate!"
+ end
+
+ if ArgsTable[6] == "Refill" then -- Argtable[6] is the round type. If it's refill it shouldn't be loaded into guns, so we refuse to change to it
+ return false, "Refill ammo type is only avaliable for new crates!"
+ end
+
+ if ArgsTable[5] ~= self.RoundId then -- Argtable[5] is the weapon ID the new ammo loads into
+ for Key, Gun in pairs( self.Master ) do
+ if IsValid( Gun ) then
+ Gun:Unlink( self )
+ end
+ end
+ msg = "New ammo type loaded, crate unlinked."
+ else -- ammotype wasn't changed, but let's check if new roundtype is blacklisted
+ local Blacklist = ACF.AmmoBlacklist[ ArgsTable[6] ] or {}
+
+ for Key, Gun in pairs( self.Master ) do
+ if IsValid( Gun ) and table.HasValue( Blacklist, Gun.Class ) then
+ Gun:Unlink( self )
+ msg = "New round type cannot be used with linked gun, crate unlinked."
+ end
+ end
+ end
+
+ local AmmoPercent = self.Ammo/math.max(self.Capacity,1)
+
+ self:CreateAmmo(ArgsTable[4], ArgsTable[5], ArgsTable[6], ArgsTable[7], ArgsTable[8], ArgsTable[9], ArgsTable[10], ArgsTable[11], ArgsTable[12], ArgsTable[13], ArgsTable[14])
+
+ self.Ammo = math.floor(self.Capacity*AmmoPercent)
+
+ self.LastMass = 1 -- force update of mass
+ self:UpdateMass()
+
+ return true, msg
+
+end
+
+function ENT:UpdateOverlayText()
+
+ local roundType = self.RoundType
+
+ if self.BulletData.Tracer and self.BulletData.Tracer > 0 then
+ roundType = roundType .. "-T"
+ end
+
+ local text = roundType .. " - " .. self.Ammo .. " / " .. self.Capacity
+ --text = text .. "\nRound Type: " .. self.RoundType
+
+ local RoundData = ACF.RoundTypes[ self.RoundType ]
+
+ if RoundData and RoundData.cratetxt then
+ text = text .. "\n" .. RoundData.cratetxt( self.BulletData, self )
+ end
+
+ if not self.Legal then
+ text = text .. "\nNot legal, disabled for " .. math.ceil(self.NextLegalCheck - ACF.CurTime) .. "s\nIssues: " .. self.LegalIssues
+ end
+
+ self:SetOverlayText( text )
+
+end
+
+function ENT:CreateAmmo(Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
+
+ local GunData = list.Get("ACFEnts").Guns[Data1]
+ if not GunData then
+ self:Remove()
+ return
+ end
+
+ --Data 1 to 4 are should always be Round ID, Round Type, Propellant lenght, Projectile lenght
+ self.RoundId = Data1 --Weapon this round loads into, ie 140mmC, 105mmH ...
+ self.RoundType = Data2 --Type of round, IE AP, HE, HEAT ...
+ self.RoundPropellant = Data3--Lenght of propellant
+ self.RoundProjectile = Data4--Lenght of the projectile
+ self.RoundData5 = ( Data5 or 0 )
+ self.RoundData6 = ( Data6 or 0 )
+ self.RoundData7 = ( Data7 or 0 )
+ self.RoundData8 = ( Data8 or 0 )
+ self.RoundData9 = ( Data9 or 0 )
+ self.RoundData10 = ( Data10 or 0 )
+
+ local PlayerData = {}
+ PlayerData.Id = self.RoundId
+ PlayerData.Type = self.RoundType
+ PlayerData.PropLength = self.RoundPropellant
+ PlayerData.ProjLength = self.RoundProjectile
+ PlayerData.Data5 = self.RoundData5
+ PlayerData.Data6 = self.RoundData6
+ PlayerData.Data7 = self.RoundData7
+ PlayerData.Data8 = self.RoundData8
+ PlayerData.Data9 = self.RoundData9
+ PlayerData.Data10 = self.RoundData10
+ self.ConvertData = ACF.RoundTypes[self.RoundType].convert
+ self.BulletData = self:ConvertData( PlayerData )
+
+ local Efficiency = 0.1576 * ACF.AmmoMod
+ local vol = math.floor(self:GetPhysicsObject():GetVolume())
+ self.Volume = vol*Efficiency
+ local CapMul = (vol > 40250) and ((math.log(vol*0.00066)/math.log(2)-4)*0.15+1) or 1
+
+ local roundType2 = self.RoundType
+ local MassMod = 0
+
+
+ if roundType2 == "APFSDS" then
+ MassMod = 11
+
+ elseif roundType2 == "APDS" then
+ MassMod = 5.25
+
+ elseif roundType2 == "APCR" then
+ MassMod = 5
+
+
+ else MassMod = 1
+
+ end
+
+
+
+
+
+
+
+
+
+
+ self.Capacity = math.floor(CapMul*self.Volume*16.38/self.BulletData.RoundVolume)
+ self.AmmoMassMax = (self.BulletData.ProjMass*MassMod + self.BulletData.PropMass) * self.Capacity * 2 -- why *2 ?
+ self.Caliber = GunData.caliber
+
+
+
+ self.RoFMul = (vol > 27000) and (1-(math.log(vol*0.00066)/math.log(2)-4)*0.2) or 1 --*0.0625 for 25% @ 4x8x8, 0.025 10%, 0.0375 15%, 0.05 20% --0.23 karb edit for cannon rof 2. changed to start from 2x3x4 instead of 2x4x4
+
+ self:SetNWString( "Ammo", self.Ammo )
+ self:SetNWString( "WireName", GunData.name .. " Ammo" )
+
+ self.NetworkData = ACF.RoundTypes[self.RoundType].network
+ self:NetworkData( self.BulletData )
+
+ self:UpdateOverlayText()
+
+end
+
+function ENT:UpdateMass()
+ self.Mass = self.EmptyMass + self.AmmoMassMax*(self.Ammo/math.max(self.Capacity,1))
+
+ --reduce superflous engine calls, update crate mass every 5 kgs change or every 10s-15s
+ if math.abs(self.LastMass - self.Mass) > 5 or CurTime() > self.NextMassUpdate then
+ self.LastMass = self.Mass
+ self.NextMassUpdate = CurTime()+math.Rand(10,15)
+ local phys = self:GetPhysicsObject()
+ if (phys:IsValid()) then
+ phys:SetMass( self.Mass )
+ end
+ end
+
+end
+
+function ENT:GetInaccuracy()
+ local SpreadScale = ACF.SpreadScale
+ local inaccuracy = 0
+ local Gun = list.Get("ACFEnts").Guns[self.RoundId]
+
+ if Gun then
+ local Classes = list.Get("ACFClasses")
+ inaccuracy = (Classes.GunClass[Gun.gunclass] or {spread = 0}).spread
+ end
+
+ local coneAng = inaccuracy * ACF.GunInaccuracyScale
+ return coneAng
+end
+
+function ENT:TriggerInput( iname, value )
+
+ if (iname == "Active") then
+ if value > 0 and self.Legal then
+ self.Load = true
+ self:FirstLoad()
+ else
+ self.Load = false
+ end
+ elseif (iname == "Fuse Length" and value > 0 and (self.BulletData.RoundType == "HE" or self.BulletData.RoundType == "APHE")) then
+ end
+
+end
+
+function ENT:FirstLoad()
+
+ for Key,Value in pairs(self.Master) do
+ local Gun = self.Master[Key]
+ if IsValid(Gun) and Gun.FirstLoad and Gun.BulletData.Type == "Empty" and Gun.Legal then
+ Gun:LoadAmmo(false, false)
+ end
+ end
+
+end
+
+function ENT:Think()
+
+ if ACF.CurTime > self.NextLegalCheck then
+ --local minmass = math.floor(self.EmptyMass+self.AmmoMassMax*((self.Ammo-1)/math.max(self.Capacity,1)))-5 -- some possible weirdness with heavy shells, and refills. just going to check above empty mass
+ self.Legal, self.LegalIssues = ACF_CheckLegal(self, self.Model, math.floor(self.EmptyMass), nil, false, true, false, true)
+ self.NextLegalCheck = ACF.LegalSettings:NextCheck(self.Legal)
+ self:UpdateOverlayText()
+
+ if not self.Legal then
+ --if self.Load then self:TriggerInput("Active",0) end
+ self.Load = false
+ end
+ end
+
+ self:UpdateMass()
+
+ if self.Ammo ~= self.AmmoLast or not self.Legal then
+ self:UpdateOverlayText()
+ self.AmmoLast = self.Ammo
+ end
+
+ local color = self:GetColor()
+ self:SetNWVector("TracerColour", Vector( color.r, color.g, color.b ) )
+
+ local cvarGrav = GetConVar("sv_gravity")
+ local vec = Vector(0,0,cvarGrav:GetInt()*-1)
+ if( self.sitp_inspace ) then
+ vec = Vector(0, 0, 0)
+ end
+
+ self:SetNWVector("Accel", vec)
+
+ self:NextThink( CurTime() + 1 )
+
+ -- cookoff handling
+ if self.Damaged then
+ if self.Ammo <= 1 or self.Damaged < CurTime() then -- immediately detonate if there's 1 or 0 shells
+ ACF_ScaledExplosion( self ) -- going to let empty crates harmlessly poot still, as an audio cue it died
+ else
+ if not (self.BulletData.Type == "Refill") then
+ if math.Rand(0,150) > self.BulletData.RoundVolume^0.5 and math.Rand(0,1) < self.Ammo/math.max(self.Capacity,1) and ACF.RoundTypes[self.BulletData.Type] then
+ self:EmitSound( "ambient/explosions/explode_4.wav", 350, math.max(255 - self.BulletData.PropMass*100,60) )
+ local Speed = ACF_MuzzleVelocity( self.BulletData.PropMass, self.BulletData.ProjMass/2, self.Caliber )
+
+ self.BulletData.Pos = self:LocalToWorld(self:OBBCenter() + VectorRand()*(self:OBBMaxs()-self:OBBMins())/2)
+ self.BulletData.Flight = (VectorRand()):GetNormalized() * Speed * 39.37 + self:GetVelocity()
+ self.BulletData.Owner = self.Inflictor or self.Owner
+ self.BulletData.Gun = self
+ self.BulletData.Crate = self:EntIndex()
+ self.CreateShell = ACF.RoundTypes[self.BulletData.Type].create
+ self:CreateShell( self.BulletData )
+
+ self.Ammo = self.Ammo - 1
+
+ end
+ end
+ self:NextThink( CurTime() + 0.01 + self.BulletData.RoundVolume^0.5/100 )
+ end
+
+ -- Completely new, fresh, genius, beautiful, flawless refill system.
+ elseif self.RoundType == "Refill" and self.Ammo > 0 and self.Load then
+ for _,Ammo in pairs( ACF.AmmoCrates ) do
+ if Ammo.RoundType ~= "Refill" then
+ local dist = self:GetPos():Distance(Ammo:GetPos())
+ if dist < ACF.RefillDistance then
+
+ if Ammo.Capacity > Ammo.Ammo then
+ self.SupplyingTo = self.SupplyingTo or {}
+ if not table.HasValue( self.SupplyingTo, Ammo:EntIndex() ) then
+ table.insert(self.SupplyingTo, Ammo:EntIndex())
+ self:RefillEffect( Ammo )
+ end
+
+ local Supply = math.ceil((50000/((Ammo.BulletData.ProjMass+Ammo.BulletData.PropMass)*1000))/dist)
+ --Msg(tostring(50000).."/"..((Ammo.BulletData.ProjMass+Ammo.BulletData.PropMass)*1000).."/"..dist.."="..Supply.."\n")
+ local Transfert = math.min(Supply, Ammo.Capacity - Ammo.Ammo)
+ Ammo.Ammo = Ammo.Ammo + Transfert
+ self.Ammo = self.Ammo - Transfert
+
+ Ammo.Supplied = true
+ Ammo.Entity:EmitSound( "items/ammo_pickup.wav", 350, 80, 0.30 )
+ end
+ end
+ end
+ end
+ end
+
+ -- checks to stop supply
+ if self.SupplyingTo then
+ for k, EntID in pairs( self.SupplyingTo ) do
+ local Ammo = ents.GetByIndex(EntID)
+ if not IsValid( Ammo ) then
+ table.remove(self.SupplyingTo, k)
+ self:StopRefillEffect( EntID )
+ else
+ local dist = self:GetPos():Distance(Ammo:GetPos())
+ -- If ammo crate is out of refill max distance or is full or our refill crate is damaged or just in-active then stop refiliing it.
+ if (dist > ACF.RefillDistance) or (Ammo.Capacity <= Ammo.Ammo) or self.Damaged or not self.Load or not Ammo.Legal then
+ table.remove(self.SupplyingTo, k)
+ self:StopRefillEffect( EntID )
+ end
+ end
+ end
+ end
+
+ Wire_TriggerOutput(self, "Munitions", self.Ammo)
+ return true
+
+end
+
+function ENT:RefillEffect( Target )
+ umsg.Start("ACF_RefillEffect")
+ umsg.Float( self:EntIndex() )
+ umsg.Float( Target:EntIndex() )
+ umsg.String( Target.RoundType )
+ umsg.End()
+end
+
+function ENT:StopRefillEffect( TargetID )
+ umsg.Start("ACF_StopRefillEffect")
+ umsg.Float( self:EntIndex() )
+ umsg.Float( TargetID )
+ umsg.End()
+end
+
+function ENT:ConvertData()
+ --You overwrite this with your own function, defined in the ammo definition file
+end
+
+function ENT:NetworkData()
+ --You overwrite this with your own function, defined in the ammo definition file
+end
+
+function ENT:OnRemove()
+
+ for Key,Value in pairs(self.Master) do
+ if self.Master[Key] and self.Master[Key]:IsValid() then
+ self.Master[Key]:Unlink( self )
+ self.Ammo = 0
+ end
+ end
+ for k,v in pairs(ACF.AmmoCrates) do
+ if v == self then
+ table.remove(ACF.AmmoCrates,k)
+ end
+ end
+
+end
diff --git a/lua/entities/acf_engine.lua b/lua/entities/acf_engine.lua
new file mode 100644
index 000000000..a10e50c90
--- /dev/null
+++ b/lua/entities/acf_engine.lua
@@ -0,0 +1,882 @@
+
+AddCSLuaFile()
+
+DEFINE_BASECLASS( "base_wire_entity" )
+
+ENT.PrintName = "ACF Engine"
+ENT.WireDebugName = "ACF Engine"
+
+if CLIENT then
+
+ local ACF_EngineInfoWhileSeated = CreateClientConVar("ACF_EngineInfoWhileSeated", 0, true, false)
+
+ -- copied from base_wire_entity: DoNormalDraw's notip arg isn't accessible from ENT:Draw defined there.
+ function ENT:Draw()
+
+ local lply = LocalPlayer()
+ local hideBubble = not GetConVar("ACF_EngineInfoWhileSeated"):GetBool() and IsValid(lply) and lply:InVehicle()
+
+ self.BaseClass.DoNormalDraw(self, false, hideBubble)
+ Wire_Render(self)
+
+ if self.GetBeamLength and (not self.GetShowBeam or self:GetShowBeam()) then
+ -- Every SENT that has GetBeamLength should draw a tracer. Some of them have the GetShowBeam boolean
+ Wire_DrawTracerBeam( self, 1, self.GetBeamHighlight and self:GetBeamHighlight() or false )
+ end
+
+ end
+
+ function ACFEngineGUICreate( Table )
+
+ acfmenupanel:CPanelText("Name", Table.name)
+
+ acfmenupanel.CData.DisplayModel = vgui.Create( "DModelPanel", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.DisplayModel:SetModel( Table.model )
+ acfmenupanel.CData.DisplayModel:SetCamPos( Vector( 250, 500, 250 ) )
+ acfmenupanel.CData.DisplayModel:SetLookAt( Vector( 0, 0, 0 ) )
+ acfmenupanel.CData.DisplayModel:SetFOV( 20 )
+ acfmenupanel.CData.DisplayModel:SetSize(acfmenupanel:GetWide(),acfmenupanel:GetWide())
+ acfmenupanel.CData.DisplayModel.LayoutEntity = function( panel, entity ) end
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.DisplayModel )
+
+ acfmenupanel:CPanelText("Desc", Table.desc)
+
+ local peakkw
+ local peakkwrpm
+ local pbmin
+ local pbmax
+
+ if (Table.iselec == true )then --elecs and turbs get peak power in middle of rpm range
+ peakkw = ( Table.torque * ( 1 + Table.peakmaxrpm / Table.limitrpm )) * Table.limitrpm / (4*9548.8) --adjust torque to 1 rpm maximum, assuming a linear decrease from a max @ 1 rpm to min @ limiter
+ peakkwrpm = math.floor(Table.limitrpm / 2)
+ pbmin = Table.idlerpm
+ pbmax = peakkwrpm
+ else
+ peakkw = Table.torque * Table.peakmaxrpm / 9548.8
+ peakkwrpm = Table.peakmaxrpm
+ pbmin = Table.peakminrpm
+ pbmax = Table.peakmaxrpm
+ end
+
+ if Table.requiresfuel then --if fuel required, show max power with fuel at top, no point in doing it twice
+ acfmenupanel:CPanelText("Power", "\nPeak Power : "..math.floor(peakkw*ACF.TorqueBoost).." kW / "..math.Round(peakkw*ACF.TorqueBoost*1.34).." HP @ "..peakkwrpm.." RPM")
+ acfmenupanel:CPanelText("Torque", "Peak Torque : "..(Table.torque*ACF.TorqueBoost).." n/m / "..math.Round(Table.torque*ACF.TorqueBoost*0.73).." ft-lb")
+ else
+ acfmenupanel:CPanelText("Power", "\nPeak Power : "..math.floor(peakkw).." kW / "..math.Round(peakkw*1.34).." HP @ "..peakkwrpm.." RPM")
+ acfmenupanel:CPanelText("Torque", "Peak Torque : "..(Table.torque).." n/m / "..math.Round(Table.torque*0.73).." ft-lb")
+ end
+
+ acfmenupanel:CPanelText("RPM", "Idle : "..(Table.idlerpm).." RPM\nPowerband : "..(pbmin).."-"..(pbmax).." RPM\nRedline : "..(Table.limitrpm).." RPM")
+ acfmenupanel:CPanelText("Weight", "Weight : "..(Table.weight).." kg")
+
+
+ acfmenupanel:CPanelText("FuelType", "\nFuel Type : "..(Table.fuel))
+
+ if Table.fuel == "Electric" then
+ local cons = ACF.ElecRate * peakkw / ACF.Efficiency[Table.enginetype]
+ acfmenupanel:CPanelText("FuelCons", "Peak energy use : "..math.Round(cons,1).." kW / "..math.Round(0.06*cons,1).." MJ/min")
+ elseif Table.fuel == "Multifuel" then
+ local petrolcons = ACF.FuelRate * ACF.Efficiency[Table.enginetype] * ACF.TorqueBoost * peakkw / (60 * ACF.FuelDensity.Petrol)
+ local dieselcons = ACF.FuelRate * ACF.Efficiency[Table.enginetype] * ACF.TorqueBoost * peakkw / (60 * ACF.FuelDensity.Diesel)
+ acfmenupanel:CPanelText("FuelConsP", "Petrol Use at "..peakkwrpm.." rpm : "..math.Round(petrolcons,2).." liters/min / "..math.Round(0.264*petrolcons,2).." gallons/min")
+ acfmenupanel:CPanelText("FuelConsD", "Diesel Use at "..peakkwrpm.." rpm : "..math.Round(dieselcons,2).." liters/min / "..math.Round(0.264*dieselcons,2).." gallons/min")
+ else
+ local fuelcons = ACF.FuelRate * ACF.Efficiency[Table.enginetype] * ACF.TorqueBoost * peakkw / (60 * ACF.FuelDensity[Table.fuel])
+ acfmenupanel:CPanelText("FuelCons", (Table.fuel).." Use at "..peakkwrpm.." rpm : "..math.Round(fuelcons,2).." liters/min / "..math.Round(0.264*fuelcons,2).." gallons/min")
+ end
+
+ if Table.requiresfuel then
+ acfmenupanel:CPanelText("Fuelreq", "REQUIRES FUEL")
+ else
+ acfmenupanel:CPanelText("FueledPower", "\nWhen supplied with fuel:\nPeak Power : "..math.floor(peakkw*ACF.TorqueBoost).." kW / "..math.Round(peakkw*ACF.TorqueBoost*1.34).." HP @ "..peakkwrpm.." RPM")
+ acfmenupanel:CPanelText("FueledTorque", "Peak Torque : "..(Table.torque*ACF.TorqueBoost).." n/m / "..math.Round(Table.torque*ACF.TorqueBoost*0.73).." ft-lb")
+ end
+
+ acfmenupanel.CustomDisplay:PerformLayout()
+
+ end
+
+ return
+
+end
+
+function ENT:Initialize()
+
+ self.Throttle = 0
+ self.Active = false
+ self.IsMaster = true
+ self.GearLink = {} -- a "Link" has these components: Ent, Rope, RopeLen, ReqTq
+ self.FuelLink = {}
+
+ self.NextUpdate = 0
+ self.LastThink = 0
+ self.MassRatio = 1
+ self.FuelTank = 0
+ self.CanUpdate = true
+ self.RequiresFuel = false
+ self.NextLegalCheck = ACF.CurTime + 30 -- give any spawning issues time to iron themselves out
+ self.Legal = true
+ self.LegalIssues = ""
+
+ self.Inputs = Wire_CreateInputs( self, { "Active", "Throttle" } ) --use fuel input?
+ self.Outputs = WireLib.CreateSpecialOutputs( self, { "RPM", "Torque", "Power", "Fuel Use", "Entity", "Mass", "Physical Mass" }, { "NORMAL","NORMAL","NORMAL", "NORMAL", "ENTITY", "NORMAL", "NORMAL" } )
+ Wire_TriggerOutput( self, "Entity", self )
+ self.WireDebugName = "ACF Engine"
+
+end
+
+function MakeACF_Engine(Owner, Pos, Angle, Id)
+
+ if not Owner:CheckLimit("_acf_misc") then return false end
+
+ local Engine = ents.Create( "acf_engine" )
+ if not IsValid( Engine ) then return false end
+
+ local EID
+ local List = list.Get("ACFEnts")
+ if List.Mobility[Id] then EID = Id else EID = "5.7-V8" end
+ local Lookup = List.Mobility[EID]
+
+ Engine:SetAngles(Angle)
+ Engine:SetPos(Pos)
+ Engine:Spawn()
+ Engine:SetPlayer(Owner)
+ Engine.Owner = Owner
+ Engine.Id = EID
+
+ Engine.Model = Lookup.model
+ Engine.SoundPath = Lookup.sound
+ Engine.Weight = Lookup.weight
+ Engine.PeakTorque = Lookup.torque
+ Engine.PeakTorqueHeld = Lookup.torque
+ Engine.IdleRPM = Lookup.idlerpm
+ Engine.PeakMinRPM = Lookup.peakminrpm
+ Engine.PeakMaxRPM = Lookup.peakmaxrpm
+ Engine.LimitRPM = Lookup.limitrpm
+ Engine.Inertia = Lookup.flywheelmass*(3.1416)^2
+ Engine.iselec = Lookup.iselec
+ Engine.FlywheelOverride = Lookup.flywheeloverride
+ Engine.IsTrans = Lookup.istrans -- driveshaft outputs to the side
+ Engine.FuelType = Lookup.fuel or "Petrol"
+ Engine.EngineType = Lookup.enginetype or "GenericPetrol"
+ Engine.RequiresFuel = Lookup.requiresfuel
+ Engine.SoundPitch = Lookup.pitch or 1
+ Engine.SpecialHealth = true
+ Engine.SpecialDamage = true
+ Engine.TorqueMult = 1
+ Engine.FuelTank = 0
+
+ Engine.TorqueScale = ACF.TorqueScale[Engine.EngineType]
+
+ --calculate boosted peak kw
+ if Engine.EngineType == "Turbine" or Engine.EngineType == "Electric" then
+ Engine.peakkw = ( Engine.PeakTorque * ( 1 + Engine.PeakMaxRPM / Engine.LimitRPM )) * Engine.LimitRPM / (4*9548.8) --adjust torque to 1 rpm maximum, assuming a linear decrease from a max @ 1 rpm to min @ limiter
+ Engine.PeakKwRPM = math.floor(Engine.LimitRPM / 2)
+ else
+ Engine.peakkw = Engine.PeakTorque * Engine.PeakMaxRPM / 9548.8
+ Engine.PeakKwRPM = Engine.PeakMaxRPM
+ end
+
+ --calculate base fuel usage
+ if Engine.EngineType == "Electric" then
+ Engine.FuelUse = ACF.ElecRate / (ACF.Efficiency[Engine.EngineType] * 60 * 60) --elecs use current power output, not max
+ else
+ Engine.FuelUse = ACF.TorqueBoost * ACF.FuelRate * ACF.Efficiency[Engine.EngineType] * Engine.peakkw / (60 * 60)
+ end
+
+ Engine.FlyRPM = 0
+ Engine:SetModel( Engine.Model )
+ Engine.Sound = nil
+ Engine.RPM = {}
+
+ Engine:PhysicsInit( SOLID_VPHYSICS )
+ Engine:SetMoveType( MOVETYPE_VPHYSICS )
+ Engine:SetSolid( SOLID_VPHYSICS )
+
+ Engine.Out = Engine:WorldToLocal(Engine:GetAttachment(Engine:LookupAttachment( "driveshaft" )).Pos)
+
+ local phys = Engine:GetPhysicsObject()
+ if IsValid( phys ) then
+ phys:SetMass( Engine.Weight )
+ Engine.ModelInertia = 0.99 * phys:GetInertia()/phys:GetMass() -- giving a little wiggle room
+ end
+
+ Engine:SetNWString( "WireName", Lookup.name )
+ Engine:UpdateOverlayText()
+
+ Owner:AddCount("_acf_misc", Engine)
+ Owner:AddCleanup( "acfmenu", Engine )
+
+ ACF_Activate( Engine, 0 )
+
+ return Engine
+end
+list.Set( "ACFCvars", "acf_engine", {"id"} )
+duplicator.RegisterEntityClass("acf_engine", MakeACF_Engine, "Pos", "Angle", "Id")
+
+function ENT:Update( ArgsTable )
+ -- That table is the player data, as sorted in the ACFCvars above, with player who shot,
+ -- and pos and angle of the tool trace inserted at the start
+
+ if self.Active then
+ return false, "Turn off the engine before updating it!"
+ end
+
+ if ArgsTable[1] ~= self.Owner then -- Argtable[1] is the player that shot the tool
+ return false, "You don't own that engine!"
+ end
+
+ local Id = ArgsTable[4] -- Argtable[4] is the engine ID
+ local Lookup = list.Get("ACFEnts").Mobility[Id]
+
+ if Lookup.model ~= self.Model then
+ return false, "The new engine must have the same model!"
+ end
+
+ local Feedback = ""
+ if Lookup.fuel != self.FuelType then
+ Feedback = " Fuel type changed, fuel tanks unlinked."
+ for Key,Value in pairs(self.FuelLink) do
+ table.remove(self.FuelLink,Key)
+ --need to remove from tank master?
+ end
+ end
+
+ self.Id = Id
+ self.SoundPath = Lookup.sound
+ self.Weight = Lookup.weight
+ self.PeakTorque = Lookup.torque
+ self.PeakTorqueHeld = Lookup.torque
+ self.IdleRPM = Lookup.idlerpm
+ self.PeakMinRPM = Lookup.peakminrpm
+ self.PeakMaxRPM = Lookup.peakmaxrpm
+ self.LimitRPM = Lookup.limitrpm
+ self.Inertia = Lookup.flywheelmass*(3.1416)^2
+ self.iselec = Lookup.iselec -- is the engine electric?
+ self.FlywheelOverride = Lookup.flywheeloverride -- modifies rpm drag on iselec==true
+ self.IsTrans = Lookup.istrans
+ self.FuelType = Lookup.fuel
+ self.EngineType = Lookup.enginetype
+ self.RequiresFuel = Lookup.requiresfuel
+ self.SoundPitch = Lookup.pitch or 1
+ self.SpecialHealth = true
+ self.SpecialDamage = true
+ self.TorqueMult = self.TorqueMult or 1
+ self.FuelTank = 0
+
+ self.TorqueScale = ACF.TorqueScale[self.EngineType]
+
+ --calculate boosted peak kw
+ if self.EngineType == "Turbine" or self.EngineType == "Electric" then
+ self.peakkw = ( self.PeakTorque * ( 1 + self.PeakMaxRPM / self.LimitRPM )) * self.LimitRPM / (4*9548.8) --adjust torque to 1 rpm maximum, assuming a linear decrease from a max @ 1 rpm to min @ limiter
+ self.PeakKwRPM = math.floor(self.LimitRPM / 2)
+ else
+ self.peakkw = self.PeakTorque * self.PeakMaxRPM / 9548.8
+ self.PeakKwRPM = self.PeakMaxRPM
+ end
+
+ --calculate base fuel usage
+ if self.EngineType == "Electric" then
+ self.FuelUse = ACF.ElecRate / (ACF.Efficiency[self.EngineType] * 60 * 60) --elecs use current power output, not max
+ else
+ self.FuelUse = ACF.TorqueBoost * ACF.FuelRate * ACF.Efficiency[self.EngineType] * self.peakkw / (60 * 60)
+ end
+
+ self:SetModel( self.Model )
+ self:SetSolid( SOLID_VPHYSICS )
+ self.Out = self:WorldToLocal(self:GetAttachment(self:LookupAttachment( "driveshaft" )).Pos)
+
+ local phys = self:GetPhysicsObject()
+ if IsValid( phys ) then
+ phys:SetMass( self.Weight )
+ end
+
+ self:SetNWString( "WireName", Lookup.name )
+ self:UpdateOverlayText()
+
+ ACF_Activate( self, 1 )
+
+ return true, "Engine updated successfully!"..Feedback
+end
+
+function ENT:UpdateOverlayText()
+
+ local pbmin
+ local pbmax
+
+ if (self.iselec == true )then --elecs and turbs get peak power in middle of rpm range
+ pbmin = self.IdleRPM
+ pbmax = math.floor(self.LimitRPM / 2)
+ else
+ pbmin = self.PeakMinRPM
+ pbmax = self.PeakMaxRPM
+ end
+ local SpecialBoost = self.RequiresFuel and ACF.TorqueBoost or 1
+ local text = "Power: " .. math.Round( self.peakkw * SpecialBoost ) .. " kW / " .. math.Round( self.peakkw * SpecialBoost * 1.34 ) .. " hp\n"
+ text = text .. "Torque: " .. math.Round( self.PeakTorque * SpecialBoost ) .. " Nm / " .. math.Round( self.PeakTorque * SpecialBoost * 0.73 ) .. " ft-lb\n"
+ text = text .. "Powerband: " .. pbmin .. " - " .. pbmax .. " RPM\n"
+ text = text .. "Redline: " .. self.LimitRPM .. " RPM"
+
+ if not self.Legal then
+ text = text .. "\nNot legal, disabled for " .. math.ceil(self.NextLegalCheck - ACF.CurTime) .. "s\nIssues: " .. self.LegalIssues
+ end
+
+ self:SetOverlayText( text )
+
+end
+
+function ENT:TriggerInput( iname, value )
+
+ if (iname == "Throttle") then
+ self.Throttle = math.Clamp(value,0,100)/100
+ elseif (iname == "Active") then
+ if (value > 0 and not self.Active and self.Legal) then
+ --make sure we have fuel
+ local HasFuel
+ if not self.RequiresFuel then
+ HasFuel = true
+ else
+ for _,fueltank in pairs(self.FuelLink) do
+ if fueltank.Fuel > 0 and fueltank.Active and fueltank.Legal then HasFuel = true break end
+ end
+ end
+
+ if HasFuel then
+ self.Active = true
+ if not (self.SoundPath=="") then
+ self.Sound = CreateSound(self, self.SoundPath)
+ self.Sound:PlayEx(0.5,100)
+ end
+ self:ACFInit()
+ end
+ elseif (value <= 0 and self.Active) then
+ self.Active = false
+ self.FlyRPM = 0
+ self.RPM = {}
+ self.RPM[1] = self.IdleRPM
+ if self.Sound then
+ self.Sound:Stop()
+ end
+ self.Sound = nil
+ Wire_TriggerOutput( self, "RPM", 0 )
+ Wire_TriggerOutput( self, "Torque", 0 )
+ Wire_TriggerOutput( self, "Power", 0 )
+ Wire_TriggerOutput( self, "Fuel Use", 0 )
+ end
+ end
+end
+
+function ENT:ACF_Activate()
+ --Density of steel = 7.8g cm3 so 7.8kg for a 1mx1m plate 1m thick
+ local Entity = self
+ Entity.ACF = Entity.ACF or {}
+
+ local Count
+ local PhysObj = Entity:GetPhysicsObject()
+ if PhysObj:GetMesh() then Count = #PhysObj:GetMesh() end
+ if PhysObj:IsValid() and Count and Count>100 then
+
+ if not Entity.ACF.Aera then
+ Entity.ACF.Aera = (PhysObj:GetSurfaceArea() * 6.45) * 0.52505066107
+ end
+ --if not Entity.ACF.Volume then
+ -- Entity.ACF.Volume = (PhysObj:GetVolume() * 16.38)
+ --end
+ else
+ local Size = Entity.OBBMaxs(Entity) - Entity.OBBMins(Entity)
+ if not Entity.ACF.Aera then
+ Entity.ACF.Aera = ((Size.x * Size.y)+(Size.x * Size.z)+(Size.y * Size.z)) * 6.45
+ end
+ --if not Entity.ACF.Volume then
+ -- Entity.ACF.Volume = Size.x * Size.y * Size.z * 16.38
+ --end
+ end
+
+ Entity.ACF.Ductility = Entity.ACF.Ductility or 0
+ --local Area = (Entity.ACF.Aera+Entity.ACF.Aera*math.Clamp(Entity.ACF.Ductility,-0.8,0.8))
+ local Area = (Entity.ACF.Aera)
+ --local Armour = (Entity:GetPhysicsObject():GetMass()*1000 / Area / 0.78) / (1 + math.Clamp(Entity.ACF.Ductility, -0.8, 0.8))^(1/2) --So we get the equivalent thickness of that prop in mm if all it's weight was a steel plate
+ local Armour = (Entity:GetPhysicsObject():GetMass()*1000 / Area / 0.78)
+ --local Health = (Area/ACF.Threshold) * (1 + math.Clamp(Entity.ACF.Ductility, -0.8, 0.8)) --Setting the threshold of the prop aera gone
+ local Health = (Area/ACF.Threshold)
+
+ local Percent = 1
+
+ if Recalc and Entity.ACF.Health and Entity.ACF.MaxHealth then
+ Percent = Entity.ACF.Health/Entity.ACF.MaxHealth
+ end
+
+ Entity.ACF.Health = Health * Percent * ACF.EngineHPMult[self.EngineType]
+ Entity.ACF.MaxHealth = Health * ACF.EngineHPMult[self.EngineType]
+ Entity.ACF.Armour = Armour * (0.5 + Percent/2)
+ Entity.ACF.MaxArmour = Armour * ACF.ArmorMod
+ Entity.ACF.Type = nil
+ Entity.ACF.Mass = PhysObj:GetMass()
+ --Entity.ACF.Density = (PhysObj:GetMass()*1000)/Entity.ACF.Volume
+
+ Entity.ACF.Type = "Prop"
+ --print(Entity.ACF.Health)
+end
+
+function ENT:ACF_OnDamage( Entity, Energy, FrAera, Angle, Inflictor, Bone, Type ) --This function needs to return HitRes
+
+ local Mul = ((Type == "HEAT" and ACF.HEATMulEngine) or 1) --Heat penetrators deal bonus damage to engines
+ local HitRes = ACF_PropDamage( Entity, Energy, FrAera * Mul, Angle, Inflictor ) --Calling the standard damage prop function
+
+ return HitRes --This function needs to return HitRes
+end
+
+function ENT:Think()
+
+ if ACF.CurTime > self.NextLegalCheck then
+ self.Legal, self.LegalIssues = ACF_CheckLegal(self, self.Model, self.Weight, self.ModelInertia, false, true, false, true)
+ self.NextLegalCheck = ACF.LegalSettings:NextCheck(self.Legal)
+ self:CheckRopes()
+ self:CheckFuel()
+ self:CalcMassRatio()
+
+ self:UpdateOverlayText()
+ self.NextUpdate = ACF.CurTime + 1
+
+ if not self.Legal and self.Active then
+ self:TriggerInput("Active",0) -- disable if not legal and active
+ end
+ end
+
+ -- when not legal, update overlay displaying lockout and issues
+ if not self.Legal and ACF.CurTime > self.NextUpdate then
+ self:UpdateOverlayText()
+ self.NextUpdate = ACF.CurTime + 1
+ end
+
+ if self.Active then
+ self:CalcRPM()
+ end
+
+ self.LastThink = ACF.CurTime
+ self:NextThink( ACF.CurTime )
+ return true
+
+end
+
+
+-- specialized calcmassratio for engines
+function ENT:CalcMassRatio()
+
+ local Mass = 0
+ local PhysMass = 0
+ local Check = nil
+
+ -- get the shit that is physically attached to the vehicle
+ local PhysEnts = ACF_GetAllPhysicalConstraints( self )
+
+ -- get the wheels directly connected to the drivetrain
+ local Wheels = ACF_GetLinkedWheels(self)
+
+ -- check if any wheels aren't in the physicalconstraint tree
+ for _,Ent in pairs( Wheels ) do
+ if not PhysEnts[Ent] then -- WE GOT EM BOIS
+ Check = Ent
+ Wheels[Ent] = nil -- manual removal, idk how table.remove would handle indexing by ent. probably not well. indexing by entity sucks, please use ent id.
+ break
+ end
+ end
+
+ -- if there's a wheel that's not in the engine constraint tree, use it as a start for getting physical constraints
+ if IsValid(Check) then -- sneaky bastards trying to get away with remote engines... NOT ANYMORE
+ table.Merge(PhysEnts, Wheels) -- I mean, they'll still be remote... but they wont get free extra power from calcmass not seeing the contraption it's powering
+ ACF_GetAllPhysicalConstraints( Check, PhysEnts ) -- no need for assignment here
+ end
+
+ -- add any parented but not constrained props you sneaky bastards
+ local AllEnts = table.Copy( PhysEnts )
+ for k, v in pairs( PhysEnts ) do
+ table.Merge( AllEnts, ACF_GetAllChildren( v ) )
+ end
+
+ for k, v in pairs( AllEnts ) do
+
+ if not IsValid( v ) then continue end
+
+ local phys = v:GetPhysicsObject()
+ if not IsValid( phys ) then continue end
+
+ Mass = Mass + phys:GetMass()
+
+ if PhysEnts[ v ] then
+ PhysMass = PhysMass + phys:GetMass()
+ end
+
+ end
+
+ self.MassRatio = PhysMass / Mass
+
+ Wire_TriggerOutput( self, "Mass", math.Round( Mass, 2 ) )
+ Wire_TriggerOutput( self, "Physical Mass", math.Round( PhysMass, 2 ) )
+
+end
+
+function ENT:ACFInit()
+
+ self:CalcMassRatio()
+
+ self.LastThink = CurTime()
+ self.Torque = self.PeakTorque
+ self.FlyRPM = self.IdleRPM * 1.5
+
+end
+
+function ENT:CalcRPM()
+
+ local DeltaTime = CurTime() - self.LastThink
+ -- local AutoClutch = math.min(math.max(self.FlyRPM-self.IdleRPM,0)/(self.IdleRPM+self.LimitRPM/10),1)
+ --local ClutchRatio = math.min(Clutch/math.max(TorqueDiff,0.05),1)
+
+ --find next active tank with fuel
+ local Tank = nil
+ local boost = 1
+ local MaxTanks = #self.FuelLink
+
+ for i = 1, MaxTanks do
+ Tank = self.FuelLink[self.FuelTank+1]
+ self.FuelTank = (self.FuelTank + 1) % MaxTanks
+ if IsValid(Tank) and Tank.Fuel > 0 and Tank.Active and Tank.Legal then
+ break --return Tank
+ end
+ Tank = nil
+ i = i + 1
+ end
+
+ --calculate fuel usage
+ if Tank then
+ local Consumption
+ if self.FuelType == "Electric" then
+ Consumption = (self.Torque * self.FlyRPM / 9548.8) * self.FuelUse * DeltaTime
+ else
+ local Load = 0.3 + self.Throttle * 0.7
+ Consumption = Load * self.FuelUse * (self.FlyRPM / self.PeakKwRPM) * DeltaTime / ACF.FuelDensity[Tank.FuelType]
+ end
+ Tank.Fuel = math.max(Tank.Fuel - Consumption,0)
+ boost = ACF.TorqueBoost
+ Wire_TriggerOutput(self, "Fuel Use", math.Round(60*Consumption/DeltaTime,3))
+ elseif self.RequiresFuel then
+ self:TriggerInput( "Active", 0 ) --shut off if no fuel and requires it
+ return 0
+ else
+ Wire_TriggerOutput(self, "Fuel Use", 0)
+ end
+
+ --adjusting performance based on damage
+ self.TorqueMult = math.Clamp(((1 - self.TorqueScale) / (0.5)) * ((self.ACF.Health/self.ACF.MaxHealth) - 1) + 1, self.TorqueScale, 1)
+ self.PeakTorque = self.PeakTorqueHeld * self.TorqueMult
+
+ -- Calculate the current torque from flywheel RPM
+ self.Torque = boost * self.Throttle * math.max( self.PeakTorque * math.min( self.FlyRPM / self.PeakMinRPM, (self.LimitRPM - self.FlyRPM) / (self.LimitRPM - self.PeakMaxRPM), 1 ), 0 )
+
+ local Drag
+ if self.iselec == true then
+ Drag = self.PeakTorque * (math.max( self.FlyRPM - self.IdleRPM, 0) / self.FlywheelOverride) * (1 - self.Throttle) / self.Inertia
+ else
+ Drag = self.PeakTorque * (math.max( self.FlyRPM - self.IdleRPM, 0) / self.PeakMaxRPM) * ( 1 - self.Throttle) / self.Inertia
+ end
+
+ -- Let's accelerate the flywheel based on that torque
+ self.FlyRPM = math.max( self.FlyRPM + self.Torque / self.Inertia - Drag, 1 )
+
+ -- The gearboxes don't think on their own, it's the engine that calls them, to ensure consistent execution order
+ local Boxes = table.Count( self.GearLink )
+
+ local TotalReqTq = 0
+
+ -- Get the requirements for torque for the gearboxes (Max clutch rating minus any wheels currently spinning faster than the Flywheel)
+ for Key, Link in pairs( self.GearLink ) do
+
+ if not Link.Ent.Legal then continue end
+
+ Link.ReqTq = Link.Ent:Calc( self.FlyRPM, self.Inertia )
+ TotalReqTq = TotalReqTq + Link.ReqTq
+
+ end
+
+ -- This is the presently available torque from the engine
+ local TorqueDiff = math.max( self.FlyRPM - self.IdleRPM, 0 ) * self.Inertia
+
+ -- Calculate the ratio of total requested torque versus what's avaliable
+ local AvailRatio = math.min( TorqueDiff / TotalReqTq / Boxes, 1 )
+
+ -- Split the torque fairly between the gearboxes who need it
+ for Key, Link in pairs( self.GearLink ) do
+
+ if not Link.Ent.Legal then continue end
+
+ Link.Ent:Act( Link.ReqTq * AvailRatio * self.MassRatio, DeltaTime, self.MassRatio )
+
+ end
+
+ self.FlyRPM = self.FlyRPM - math.min( TorqueDiff, TotalReqTq ) / self.Inertia
+
+ -- Then we calc a smoothed RPM value for the sound effects
+ table.remove( self.RPM, 10 )
+ table.insert( self.RPM, 1, self.FlyRPM )
+ local SmoothRPM = 0
+ for Key, RPM in pairs( self.RPM ) do
+ SmoothRPM = SmoothRPM + (RPM or 0)
+ end
+ SmoothRPM = SmoothRPM / 10
+
+ local Power = self.Torque * SmoothRPM / 9548.8
+ Wire_TriggerOutput(self, "Torque", math.floor(self.Torque))
+ Wire_TriggerOutput(self, "Power", math.floor(Power))
+ Wire_TriggerOutput(self, "RPM", self.FlyRPM)
+
+ if self.Sound then
+ self.Sound:ChangePitch( math.min( 20 + (SmoothRPM * self.SoundPitch) / 50, 255 ), 0 )
+ self.Sound:ChangeVolume( 0.25 + (0.1 + 0.9 * ((SmoothRPM / self.LimitRPM) ^ 1.5)) * self.Throttle / 1.5, 0 )
+ end
+
+ return RPM
+end
+
+function ENT:CheckRopes()
+
+ for Key, Link in pairs( self.GearLink ) do
+
+ local Ent = Link.Ent
+
+ local OutPos = self:LocalToWorld( self.Out )
+ local InPos = Ent:LocalToWorld( Ent.In )
+
+ -- make sure it is not stretched too far
+ if OutPos:Distance( InPos ) > Link.RopeLen * 1.5 then
+ self:Unlink( Ent )
+ end
+
+ -- make sure the angle is not excessive
+ local Direction
+ if self.IsTrans then Direction = -self:GetRight() else Direction = self:GetForward() end
+
+ local DrvAngle = ( OutPos - InPos ):GetNormalized():DotProduct( Direction )
+ if DrvAngle < 0.7 then
+ self:Unlink( Ent )
+ end
+
+ end
+
+end
+
+--unlink fuel tanks out of range
+function ENT:CheckFuel()
+ for _,tank in pairs(self.FuelLink) do
+ if self:GetPos():Distance(tank:GetPos()) > 512 then
+ self:Unlink( tank )
+ soundstr = "physics/metal/metal_box_impact_bullet" .. tostring(math.random(1, 3)) .. ".wav"
+ self:EmitSound(soundstr,500,100)
+ end
+ end
+end
+
+function ENT:Link( Target )
+
+ if not IsValid( Target ) or (Target:GetClass() ~= "acf_gearbox" and Target:GetClass() ~= "acf_fueltank") then
+ return false, "Can only link to gearboxes or fuel tanks!"
+ end
+
+ if Target:GetClass() == "acf_fueltank" then
+ return self:LinkFuel( Target )
+ end
+
+ -- Check if target is already linked
+ for Key, Link in pairs( self.GearLink ) do
+ if Link.Ent == Target then
+ return false, "That is already linked to this engine!"
+ end
+ end
+
+ -- make sure the angle is not excessive
+ local InPos = Target:LocalToWorld( Target.In )
+ local OutPos = self:LocalToWorld( self.Out )
+
+ local Direction
+ if self.IsTrans then Direction = -self:GetRight() else Direction = self:GetForward() end
+
+ local DrvAngle = ( OutPos - InPos ):GetNormalized():DotProduct( Direction )
+ if DrvAngle < 0.7 then
+ return false, "Cannot link due to excessive driveshaft angle!"
+ end
+
+ local Rope = nil
+ if self.Owner:GetInfoNum( "ACF_MobilityRopeLinks", 1) == 1 then
+ Rope = constraint.CreateKeyframeRope( OutPos, 1, "cable/cable2", nil, self, self.Out, 0, Target, Target.In, 0 )
+ end
+
+ local Link = {
+ Ent = Target,
+ Rope = Rope,
+ RopeLen = ( OutPos - InPos ):Length(),
+ ReqTq = 0
+ }
+
+ table.insert( self.GearLink, Link )
+ table.insert( Target.Master, self )
+
+ return true, "Link successful!"
+end
+
+function ENT:Unlink( Target )
+
+ if Target:GetClass() == "acf_fueltank" then
+ return self:UnlinkFuel( Target )
+ end
+
+ for Key, Link in pairs( self.GearLink ) do
+
+ if Link.Ent == Target then
+
+ -- Remove any old physical ropes leftover from dupes
+ for Key, Rope in pairs( constraint.FindConstraints( Link.Ent, "Rope" ) ) do
+ if Rope.Ent1 == self or Rope.Ent2 == self then
+ Rope.Constraint:Remove()
+ end
+ end
+
+ if IsValid( Link.Rope ) then
+ Link.Rope:Remove()
+ end
+
+ table.remove( self.GearLink,Key )
+
+ return true, "Unlink successful!"
+
+ end
+
+ end
+
+ return false, "That gearbox is not linked to this engine!"
+
+end
+
+function ENT:LinkFuel( Target )
+
+ if not (self.FuelType == "Multifuel" and not (Target.FuelType == "Electric")) then
+ if self.FuelType ~= Target.FuelType then
+ return false, "Cannot link because fuel type is incompatible."
+ end
+ end
+
+ if Target.NoLinks then
+ return false, "This fuel tank doesn\'t allow linking."
+ end
+
+ for Key,Value in pairs(self.FuelLink) do
+ if Value == Target then
+ return false, "That fuel tank is already linked to this engine!"
+ end
+ end
+
+ if self:GetPos():Distance( Target:GetPos() ) > 512 then
+ return false, "Fuel tank is too far away."
+ end
+
+ table.insert( self.FuelLink, Target )
+ table.insert( Target.Master, self )
+
+ return true, "Link successful!"
+
+end
+
+function ENT:UnlinkFuel( Target )
+
+ for Key, Value in pairs( self.FuelLink ) do
+ if Value == Target then
+ table.remove( self.FuelLink, Key )
+ return true, "Unlink successful!"
+ end
+ end
+
+ return false, "That fuel tank is not linked to this engine!"
+
+end
+
+function ENT:PreEntityCopy()
+
+ //Link Saving
+ local info = {}
+ local entids = {}
+ for Key, Link in pairs( self.GearLink ) do --First clean the table of any invalid entities
+ if not IsValid( Link.Ent ) then
+ table.remove( self.GearLink, Key )
+ end
+ end
+ for Key, Link in pairs( self.GearLink ) do --Then save it
+ table.insert( entids, Link.Ent:EntIndex() )
+ end
+
+ info.entities = entids
+ if info.entities then
+ duplicator.StoreEntityModifier( self, "GearLink", info )
+ end
+
+ --fuel tank link saving
+ local fuel_info = {}
+ local fuel_entids = {}
+ for Key, Value in pairs(self.FuelLink) do --First clean the table of any invalid entities
+ if not Value:IsValid() then
+ table.remove(self.FuelLink, Value)
+ end
+ end
+ for Key, Value in pairs(self.FuelLink) do --Then save it
+ table.insert(fuel_entids, Value:EntIndex())
+ end
+
+ fuel_info.entities = fuel_entids
+ if fuel_info.entities then
+ duplicator.StoreEntityModifier( self, "FuelLink", fuel_info )
+ end
+
+ //Wire dupe info
+ self.BaseClass.PreEntityCopy( self )
+
+end
+
+function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
+
+ //Link Pasting
+ if (Ent.EntityMods) and (Ent.EntityMods.GearLink) and (Ent.EntityMods.GearLink.entities) then
+ local GearLink = Ent.EntityMods.GearLink
+ if GearLink.entities and table.Count(GearLink.entities) > 0 then
+ timer.Simple( 0, function() -- this timer is a workaround for an ad2/makespherical issue https://github.com/nrlulz/ACF/issues/14#issuecomment-22844064
+ for _,ID in pairs(GearLink.entities) do
+ local Linked = CreatedEntities[ ID ]
+ if IsValid( Linked ) then
+ self:Link( Linked )
+ end
+ end
+ end )
+ end
+ Ent.EntityMods.GearLink = nil
+ end
+
+ --fuel tank link Pasting
+ if (Ent.EntityMods) and (Ent.EntityMods.FuelLink) and (Ent.EntityMods.FuelLink.entities) then
+ local FuelLink = Ent.EntityMods.FuelLink
+ if FuelLink.entities and table.Count(FuelLink.entities) > 0 then
+ for _,ID in pairs(FuelLink.entities) do
+ local Linked = CreatedEntities[ ID ]
+ if IsValid( Linked ) then
+ self:Link( Linked )
+ end
+ end
+ end
+ Ent.EntityMods.FuelLink = nil
+ end
+
+ //Wire dupe info
+ self.BaseClass.PostEntityPaste( self, Player, Ent, CreatedEntities )
+
+end
+
+function ENT:OnRemove()
+ if self.Sound then
+ self.Sound:Stop()
+ end
+end
diff --git a/lua/entities/acf_fueltank.lua b/lua/entities/acf_fueltank.lua
new file mode 100644
index 000000000..031ba89dd
--- /dev/null
+++ b/lua/entities/acf_fueltank.lua
@@ -0,0 +1,464 @@
+AddCSLuaFile()
+
+DEFINE_BASECLASS( "base_wire_entity" )
+
+ENT.PrintName = "ACF Fuel Tank"
+ENT.WireDebugName = "ACF Fuel Tank"
+
+--don't forget:
+--armored tanks
+
+if CLIENT then
+
+ local ACF_FuelInfoWhileSeated = CreateClientConVar("ACF_FuelInfoWhileSeated", 0, true, false)
+
+ -- copied from base_wire_entity: DoNormalDraw's notip arg isn't accessible from ENT:Draw defined there.
+ function ENT:Draw()
+
+ local lply = LocalPlayer()
+ local hideBubble = not GetConVar("ACF_FuelInfoWhileSeated"):GetBool() and IsValid(lply) and lply:InVehicle()
+
+ self.BaseClass.DoNormalDraw(self, false, hideBubble)
+ Wire_Render(self)
+
+ if self.GetBeamLength and (not self.GetShowBeam or self:GetShowBeam()) then
+ -- Every SENT that has GetBeamLength should draw a tracer. Some of them have the GetShowBeam boolean
+ Wire_DrawTracerBeam( self, 1, self.GetBeamHighlight and self:GetBeamHighlight() or false )
+ end
+
+ end
+
+ function ACFFuelTankGUICreate( Table )
+ if not acfmenupanel.CustomDisplay then return end
+ if not acfmenupanel.FuelTankData then
+ acfmenupanel.FuelTankData = {}
+ acfmenupanel.FuelTankData.Id = "Tank_4x4x2"
+ acfmenupanel.FuelTankData.FuelID = "Petrol"
+ end
+
+ local Tanks = list.Get("ACFEnts").FuelTanks
+ local SortedTanks = {}
+ for n in pairs(Tanks) do table.insert(SortedTanks,n) end
+ table.sort(SortedTanks)
+
+ acfmenupanel:CPanelText("Name", Table.name)
+ acfmenupanel:CPanelText("Desc", Table.desc)
+
+ -- tank size dropbox
+ acfmenupanel.CData.TankSizeSelect = vgui.Create( "DComboBox", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.TankSizeSelect:SetSize(100, 30)
+ for k,v in ipairs(SortedTanks) do acfmenupanel.CData.TankSizeSelect:AddChoice( v ) end
+ acfmenupanel.CData.TankSizeSelect.OnSelect = function( index, value, data )
+ RunConsoleCommand( "acfmenu_data1", data )
+ acfmenupanel.FuelTankData.Id = data
+ ACFFuelTankGUIUpdate( Table )
+ end
+ acfmenupanel.CData.TankSizeSelect:SetText(acfmenupanel.FuelTankData.Id)
+ RunConsoleCommand( "acfmenu_data1", acfmenupanel.FuelTankData.Id )
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.TankSizeSelect )
+
+ -- fuel type dropbox
+ acfmenupanel.CData.FuelSelect = vgui.Create( "DComboBox", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.FuelSelect:SetSize(100, 30)
+ for Key, Value in pairs( ACF.FuelDensity ) do
+ acfmenupanel.CData.FuelSelect:AddChoice( Key )
+ end
+ acfmenupanel.CData.FuelSelect.OnSelect = function( index, value, data )
+ RunConsoleCommand( "acfmenu_data2", data )
+ acfmenupanel.FuelTankData.FuelID = data
+ ACFFuelTankGUIUpdate( Table )
+ end
+ acfmenupanel.CData.FuelSelect:SetText(acfmenupanel.FuelTankData.FuelID)
+ RunConsoleCommand( "acfmenu_data2", acfmenupanel.FuelTankData.FuelID )
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.FuelSelect )
+
+ ACFFuelTankGUIUpdate( Table )
+
+ acfmenupanel.CustomDisplay:PerformLayout()
+
+ end
+
+ function ACFFuelTankGUIUpdate( Table )
+
+ if not acfmenupanel.CustomDisplay then return end
+
+ local Tanks = list.Get("ACFEnts").FuelTanks
+
+ local TankID = acfmenupanel.FuelTankData.Id
+ local FuelID = acfmenupanel.FuelTankData.FuelID
+ local Dims = Tanks[TankID].dims
+
+ local Wall = 0.03937 --wall thickness in inches (1mm)
+ local Volume = Dims.V - (Dims.S * Wall) -- total volume of tank (cu in), reduced by wall thickness
+ local Capacity = Volume * ACF.CuIToLiter * ACF.TankVolumeMul * 0.4774 --internal volume available for fuel in liters, with magic realism number
+ local EmptyMass = ((Dims.S * Wall)*16.387)*(7.9/1000) -- total wall volume * cu in to cc * density of steel (kg/cc)
+ local Mass = EmptyMass + Capacity * ACF.FuelDensity[FuelID] -- weight of tank + weight of fuel
+
+ --fuel and tank info
+ if FuelID == "Electric" then
+ local kwh = Capacity * ACF.LiIonED
+ acfmenupanel:CPanelText("TankName", Tanks[TankID].name .. " Li-Ion Battery")
+ acfmenupanel:CPanelText("TankDesc", Tanks[TankID].desc .. "\n")
+ acfmenupanel:CPanelText("Cap", "Charge: " ..math.Round(kwh,1).. " kW hours / " ..math.Round(kwh*3.6,1).. " MJ")
+ acfmenupanel:CPanelText("Mass", "Mass: " ..math.Round(Mass,1).. " kg")
+ else
+ acfmenupanel:CPanelText("TankName", Tanks[TankID].name .. " fuel tank")
+ acfmenupanel:CPanelText("TankDesc", Tanks[TankID].desc .. "\n")
+ acfmenupanel:CPanelText("Cap", "Capacity: " ..math.Round(Capacity,1).. " liters / " ..math.Round(Capacity*0.264172,1).. " gallons")
+ acfmenupanel:CPanelText("Mass", "Full mass: " ..math.Round(Mass,1).. " kg, Empty mass: " ..math.Round(EmptyMass,1).. " kg")
+ end
+
+ local text = "\n"
+ if Tanks[TankID].nolinks then
+ text = "\nThis fuel tank won\'t link to engines. It's intended to resupply fuel to other fuel tanks."
+ end
+ acfmenupanel:CPanelText("Links", text)
+
+ --fuel tank model display
+ if not acfmenupanel.CData.DisplayModel then
+ acfmenupanel.CData.DisplayModel = vgui.Create( "DModelPanel", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.DisplayModel:SetModel( Tanks[TankID].model )
+ acfmenupanel.CData.DisplayModel:SetCamPos( Vector( 250, 500, 200 ) )
+ acfmenupanel.CData.DisplayModel:SetLookAt( Vector( 0, 0, 0 ) )
+ acfmenupanel.CData.DisplayModel:SetFOV( 10 )
+ acfmenupanel.CData.DisplayModel:SetSize(acfmenupanel:GetWide(),acfmenupanel:GetWide())
+ acfmenupanel.CData.DisplayModel.LayoutEntity = function( panel, entity ) end
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.DisplayModel )
+ end
+ acfmenupanel.CData.DisplayModel:SetModel( Tanks[TankID].model )
+
+ end
+
+ return
+
+end
+
+function ENT:Initialize()
+
+ self.CanUpdate = true
+ self.SpecialHealth = true --If true, use the ACF_Activate function defined by this ent
+ self.SpecialDamage = true --If true, use the ACF_OnDamage function defined by this ent
+ self.IsExplosive = true
+ self.Exploding = false
+
+ self.Size = 0 --outer dimensions
+ self.Volume = 0 --total internal volume in cubic inches
+ self.Capacity = 0 --max fuel capacity in liters
+ self.Fuel = 0 --current fuel level in liters
+ self.FuelType = nil
+ self.EmptyMass = 0 --mass of tank only
+ self.NextMassUpdate = 0
+ self.Id = nil --model id
+ self.Active = false
+ self.SupplyFuel = false
+ self.Leaking = 0
+ self.NextLegalCheck = ACF.CurTime + 30 -- give any spawning issues time to iron themselves out
+ self.Legal = true
+ self.LegalIssues = ""
+
+ self.Inputs = Wire_CreateInputs( self, { "Active", "Refuel Duty" } )
+ self.Outputs = WireLib.CreateSpecialOutputs( self,
+ { "Fuel", "Capacity", "Leaking", "Entity" },
+ { "NORMAL", "NORMAL", "NORMAL", "ENTITY" }
+ )
+ Wire_TriggerOutput( self, "Leaking", 0 )
+ Wire_TriggerOutput( self, "Entity", self )
+
+ self.Master = {} --engines linked to this tank
+ ACF.FuelTanks = ACF.FuelTanks or {} --master list of acf fuel tanks
+
+ self.LastThink = 0
+ self.NextThink = CurTime() + 1
+
+end
+
+function ENT:ACF_Activate( Recalc )
+
+ self.ACF = self.ACF or {}
+
+ local PhysObj = self:GetPhysicsObject()
+ if not self.ACF.Aera then
+ self.ACF.Aera = PhysObj:GetSurfaceArea() * 6.45
+ end
+ if not self.ACF.Volume then
+ self.ACF.Volume = PhysObj:GetVolume() * 1
+ end
+
+ local Armour = self.EmptyMass*1000 / self.ACF.Aera / 0.78 --So we get the equivalent thickness of that prop in mm if all it's weight was a steel plate
+ local Health = self.ACF.Volume/ACF.Threshold --Setting the threshold of the prop aera gone
+
+ local Percent = 1
+ if Recalc and self.ACF.Health and self.ACF.MaxHealth then
+ Percent = self.ACF.Health/self.ACF.MaxHealth
+ end
+
+ self.ACF.Health = Health * Percent
+ self.ACF.MaxHealth = Health
+ self.ACF.Armour = Armour * (0.5 + Percent/2)
+ self.ACF.MaxArmour = Armour
+ self.ACF.Type = nil
+ self.ACF.Mass = self.Mass
+ self.ACF.Density = (PhysObj:GetMass()*1000) / self.ACF.Volume
+ self.ACF.Type = "Prop"
+
+end
+
+function ENT:ACF_OnDamage( Entity, Energy, FrAera, Angle, Inflictor, Bone, Type ) --This function needs to return HitRes
+
+ local Mul = ((Type == "HEAT" and ACF.HEATMulFuel) or 1) --Heat penetrators deal bonus damage to fuel
+ local HitRes = ACF_PropDamage( Entity, Energy, FrAera * Mul, Angle, Inflictor ) --Calling the standard damage prop function
+
+ local NoExplode = self.FuelType == "Diesel" and not (Type == "HE" or Type == "HEAT")
+ if self.Exploding or NoExplode or not self.IsExplosive then return HitRes end
+
+ if HitRes.Kill then
+ if hook.Run( "ACF_FuelExplode", self ) == false then return HitRes end
+ self.Exploding = true
+ if( Inflictor and Inflictor:IsValid() and Inflictor:IsPlayer() ) then
+ self.Inflictor = Inflictor
+ end
+ ACF_ScaledExplosion( self )
+ return HitRes
+ end
+
+ local Ratio = (HitRes.Damage/self.ACF.Health)^0.75 --chance to explode from sheer damage, small shots = small chance
+ local ExplodeChance = (1-(self.Fuel/self.Capacity))^0.75 --chance to explode from fumes in tank, less fuel = more explodey
+
+ if math.Rand(0,1) < (ExplodeChance + Ratio) then --it's gonna blow
+ if hook.Run( "ACF_FuelExplode", self ) == false then return HitRes end
+ self.Inflictor = Inflictor
+ self.Exploding = true
+ ACF_ScaledExplosion( self )
+ else --spray some fuel around
+ self:NextThink( CurTime() + 0.1 )
+ self.Leaking = self.Leaking + self.Fuel * ((HitRes.Damage/self.ACF.Health)^1.5) * 0.25
+ end
+
+ return HitRes
+
+end
+
+function MakeACF_FuelTank(Owner, Pos, Angle, Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
+
+ if IsValid(Owner) and not Owner:CheckLimit("_acf_misc") then return false end
+
+ local SId = Data1
+ local Tanks = list.Get("ACFEnts").FuelTanks
+ if not Tanks[SId].model then return false end --SId = "Tank_4x4x2" end
+
+ local Tank = ents.Create("acf_fueltank")
+ if not IsValid(Tank) then return false end
+ Tank:SetAngles(Angle)
+ Tank:SetPos(Pos)
+ Tank:Spawn()
+ Tank:SetPlayer(Owner)
+ Tank.Owner = Owner
+
+ Tank.Id = Id
+ Tank.SizeId = SId
+ Tank.Model = Tanks[Tank.SizeId].model
+ Tank:SetModel( Tank.Model )
+
+ Tank:PhysicsInit( SOLID_VPHYSICS )
+ Tank:SetMoveType( MOVETYPE_VPHYSICS )
+ Tank:SetSolid( SOLID_VPHYSICS )
+
+ Tank.LastMass = 1
+
+ Tank:UpdateFuelTank(Id, SId, Data2)
+
+ if IsValid(Owner) then
+ Owner:AddCount( "_acf_misc", Tank )
+ Owner:AddCleanup( "acfmenu", Tank )
+ end
+
+ table.insert(ACF.FuelTanks, Tank)
+
+ return Tank
+
+end
+list.Set( "ACFCvars", "acf_fueltank", {"id", "data1", "data2"} )
+duplicator.RegisterEntityClass("acf_fueltank", MakeACF_FuelTank, "Pos", "Angle", "Id", "SizeId", "FuelType" )
+
+function ENT:UpdateFuelTank(Id, Data1, Data2)
+
+ local lookup = list.Get("ACFEnts").FuelTanks
+ local pct = 1 --how full is the tank?
+ if self.Capacity and not (self.Capacity == 0) then --if updating existing tank, keep fuel level
+ pct = self.Fuel / self.Capacity
+ end
+
+ local PhysObj = self:GetPhysicsObject()
+ local Area = PhysObj:GetSurfaceArea()
+ local Wall = 0.03937 --wall thickness in inches (1mm)
+ self.Volume = PhysObj:GetVolume() - (Area * Wall) -- total volume of tank (cu in), reduced by wall thickness
+ self.Capacity = self.Volume * ACF.CuIToLiter * ACF.TankVolumeMul * 0.4774 --internal volume available for fuel in liters, with magic realism number
+ self.EmptyMass = (Area*Wall)*16.387*(7.9/1000) -- total wall volume * cu in to cc * density of steel (kg/cc)
+
+ self.FuelType = Data2
+ self.IsExplosive = self.FuelType ~= "Electric" and lookup[Data1].explosive ~= false
+ self.NoLinks = lookup[Data1].nolinks == true
+
+ if self.FuelType == "Electric" then
+ self.Liters = self.Capacity --batteries capacity is different from internal volume
+ self.Capacity = self.Capacity * ACF.LiIonED
+ self.Fuel = pct * self.Capacity
+ else
+ self.Fuel = pct * self.Capacity
+ end
+
+ self:UpdateFuelMass()
+
+ Wire_TriggerOutput( self, "Capacity", math.Round(self.Capacity,2) )
+ self:UpdateOverlayText()
+
+end
+
+function ENT:UpdateOverlayText()
+
+ local text = "Fuel Type: " .. self.FuelType
+
+ if self.FuelType == "Electric" then
+ text = text .. "\nCharge Level: " .. math.Round( self.Fuel, 1 ) .. " kWh / " .. math.Round( self.Fuel * 3.6, 1 ) .. " MJ"
+ else
+ text = text .. "\nFuel Remaining: " .. math.Round( self.Fuel, 1 ) .. " liters / " .. math.Round( self.Fuel * 0.264172, 1 ) .. " gallons"
+ end
+
+ if not self.Legal then
+ text = text .. "\nNot legal, disabled for " .. math.ceil(self.NextLegalCheck - ACF.CurTime) .. "s\nIssues: " .. self.LegalIssues
+ end
+
+ self:SetOverlayText( text )
+
+end
+
+function ENT:UpdateFuelMass()
+
+ if self.FuelType == "Electric" then
+ self.Mass = self.EmptyMass + self.Liters * ACF.FuelDensity[self.FuelType]
+ else
+ local FuelMass = self.Fuel * ACF.FuelDensity[self.FuelType]
+ self.Mass = self.EmptyMass + FuelMass
+ end
+
+ --reduce superflous engine calls, update fuel tank mass every 5 kgs change or every 10s-15s
+ if math.abs(self.LastMass - self.Mass) > 5 or CurTime() > self.NextMassUpdate then
+ self.LastMass = self.Mass
+ self.NextMassUpdate = CurTime()+math.Rand(10,15)
+ local phys = self:GetPhysicsObject()
+ if (phys:IsValid()) then
+ phys:SetMass( self.Mass )
+ end
+ end
+
+ self:UpdateOverlayText()
+
+end
+
+function ENT:Update( ArgsTable )
+
+ local Feedback = ""
+
+ if ( ArgsTable[1] != self.Owner ) then --Argtable[1] is the player that shot the tool
+ return false, "You don't own that fuel tank!"
+ end
+
+ if ( ArgsTable[6] != self.FuelType ) then
+ for Key, Engine in pairs( self.Master ) do
+ if Engine:IsValid() then
+ Engine:Unlink( self )
+ end
+ end
+ Feedback = " New fuel type loaded, fuel tank unlinked."
+ end
+
+ self:UpdateFuelTank(ArgsTable[4], ArgsTable[5], ArgsTable[6]) --Id, SizeId, FuelType
+
+ return true, "Fuel tank successfully updated."..Feedback
+end
+
+function ENT:TriggerInput( iname, value )
+
+ if (iname == "Active") then
+ if not (value == 0) then
+ self.Active = true
+ else
+ self.Active = false
+ end
+ elseif iname == "Refuel Duty" then
+ if not (value == 0) then
+ self.SupplyFuel = true
+ else
+ self.SupplyFuel = false
+ end
+ end
+
+end
+
+function ENT:Think()
+
+ if ACF.CurTime > self.NextLegalCheck then
+ --local minmass = math.floor(self.Mass-6) -- fuel is light, may as well save complexity and just check it's above empty mass
+ self.Legal, self.LegalIssues = ACF_CheckLegal(self, self.Model, math.floor(self.EmptyMass), nil, false, true, false, true) -- mass-6, as mass update is granular to 5 kg
+ self.NextLegalCheck = ACF.LegalSettings:NextCheck(self.Legal)
+ self:UpdateOverlayText()
+ end
+
+ if self.Leaking > 0 then
+ self:NextThink( CurTime() + 0.25 )
+ self.Fuel = math.max(self.Fuel - self.Leaking,0)
+ self.Leaking = math.Clamp(self.Leaking - (1 / math.max(self.Fuel,1))^0.5, 0, self.Fuel) --fuel tanks are self healing
+ Wire_TriggerOutput(self, "Leaking", (self.Leaking > 0) and 1 or 0)
+ else
+ self:NextThink( CurTime() + 2 )
+ end
+
+ --refuelling
+ if self.Active and self.SupplyFuel and self.Fuel > 0 and self.Legal then
+ for _,Tank in pairs(ACF.FuelTanks) do
+ if self.FuelType == Tank.FuelType and not Tank.SupplyFuel and Tank.Legal then --don't refuel the refuellers, otherwise it'll be one big circlejerk
+ local dist = self:GetPos():Distance(Tank:GetPos())
+ if dist < ACF.RefillDistance then
+ if Tank.Capacity - Tank.Fuel > 0.1 then
+ local exchange = (CurTime() - self.LastThink) * ACF.RefillSpeed * (((self.FuelType == "Electric") and ACF.ElecRate) or ACF.FuelRate) / 1750 --3500
+ exchange = math.min(exchange, self.Fuel, Tank.Capacity - Tank.Fuel)
+ self.Fuel = self.Fuel - exchange
+ Tank.Fuel = Tank.Fuel + exchange
+ if Tank.FuelType == "Electric" then
+ sound.Play("ambient/energy/newspark04.wav",Tank:GetPos(),75,100,0.5)
+ else
+ sound.Play("vehicles/jetski/jetski_no_gas_start.wav",Tank:GetPos(),75,120,0.5)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ self:UpdateFuelMass()
+
+ Wire_TriggerOutput(self, "Fuel", self.Fuel)
+
+ self.LastThink = CurTime()
+
+ return true
+
+end
+
+function ENT:OnRemove()
+
+ for Key,Value in pairs(self.Master) do
+ if IsValid( self.Master[Key] ) then
+ self.Master[Key]:Unlink( self )
+ end
+ end
+
+ if #ACF.FuelTanks > 0 then
+ for k,v in pairs(ACF.FuelTanks) do
+ if v == self then
+ table.remove(ACF.FuelTanks,k)
+ end
+ end
+ end
+
+end
diff --git a/lua/entities/acf_gearbox.lua b/lua/entities/acf_gearbox.lua
new file mode 100644
index 000000000..c0cf78111
--- /dev/null
+++ b/lua/entities/acf_gearbox.lua
@@ -0,0 +1,1087 @@
+AddCSLuaFile()
+
+DEFINE_BASECLASS( "base_wire_entity" )
+
+ENT.PrintName = "ACF Gearbox"
+ENT.WireDebugName = "ACF Gearbox"
+
+if CLIENT then
+
+ local ACF_GearboxInfoWhileSeated = CreateClientConVar("ACF_GearboxInfoWhileSeated", 0, true, false)
+
+ -- copied from base_wire_entity: DoNormalDraw's notip arg isn't accessible from ENT:Draw defined there.
+ function ENT:Draw()
+
+ local lply = LocalPlayer()
+ local hideBubble = not GetConVar("ACF_GearboxInfoWhileSeated"):GetBool() and IsValid(lply) and lply:InVehicle()
+
+ self.BaseClass.DoNormalDraw(self, false, hideBubble)
+ Wire_Render(self)
+
+ if self.GetBeamLength and (not self.GetShowBeam or self:GetShowBeam()) then
+ -- Every SENT that has GetBeamLength should draw a tracer. Some of them have the GetShowBeam boolean
+ Wire_DrawTracerBeam( self, 1, self.GetBeamHighlight and self:GetBeamHighlight() or false )
+ end
+
+ end
+
+ function ACFGearboxGUICreate( Table )
+
+ if not acfmenupanel.Serialize then
+ acfmenupanel.Serialize = function( tbl, factor )
+ local str = ""
+ for i=1,7 do
+ str = str..math.Round(tbl[i] * factor,1)..","
+ end
+ RunConsoleCommand( "acfmenu_data9", str )
+ end
+ end
+
+ if not acfmenupanel.GearboxData then
+ acfmenupanel.GearboxData = {}
+ end
+
+ if not acfmenupanel.GearboxData[Table.id] then
+ acfmenupanel.GearboxData[Table.id] = {}
+ acfmenupanel.GearboxData[Table.id].GearTable = Table.geartable
+ end
+
+ if Table.auto and not acfmenupanel.GearboxData[Table.id].ShiftTable then
+ acfmenupanel.GearboxData[Table.id].ShiftTable = {10,20,30,40,50,60,70}
+ end
+
+ acfmenupanel:CPanelText("Name", Table.name)
+
+ acfmenupanel.CData.DisplayModel = vgui.Create( "DModelPanel", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.DisplayModel:SetModel( Table.model )
+ acfmenupanel.CData.DisplayModel:SetCamPos( Vector( 250, 500, 250 ) )
+ acfmenupanel.CData.DisplayModel:SetLookAt( Vector( 0, 0, 0 ) )
+ acfmenupanel.CData.DisplayModel:SetFOV( 20 )
+ acfmenupanel.CData.DisplayModel:SetSize(acfmenupanel:GetWide(),acfmenupanel:GetWide())
+ acfmenupanel.CData.DisplayModel.LayoutEntity = function( panel, entity ) end
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.DisplayModel )
+
+ acfmenupanel:CPanelText("Desc", Table.desc) --Description (Name, Desc)
+
+ if Table.auto and not acfmenupanel.CData.UnitsInput then
+ acfmenupanel.CData.UnitsInput = vgui.Create( "DComboBox", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.UnitsInput.ID = Table.id
+ acfmenupanel.CData.UnitsInput.Gears = Table.gears
+ acfmenupanel.CData.UnitsInput:SetSize( 60,22 )
+ acfmenupanel.CData.UnitsInput:SetTooltip( "If using the shift point generator, recalc after changing units." )
+ acfmenupanel.CData.UnitsInput:AddChoice( "KPH", 10.936, true )
+ acfmenupanel.CData.UnitsInput:AddChoice( "MPH", 17.6 )
+ acfmenupanel.CData.UnitsInput:AddChoice( "GMU", 1 )
+ acfmenupanel.CData.UnitsInput:SetDark( true )
+ acfmenupanel.CData.UnitsInput.OnSelect = function( panel, index, label, data )
+ acfmenupanel.Serialize( acfmenupanel.GearboxData[panel.ID].ShiftTable, data ) --dot intentional
+ end
+ acfmenupanel.CustomDisplay:AddItem(acfmenupanel.CData.UnitsInput)
+ end
+
+ if Table.cvt then
+ ACF_GearsSlider(2, acfmenupanel.GearboxData[Table.id].GearTable[2], Table.id)
+ ACF_GearsSlider(3, acfmenupanel.GearboxData[Table.id].GearTable[-3], Table.id, "Min Target RPM",true)
+ ACF_GearsSlider(4, acfmenupanel.GearboxData[Table.id].GearTable[-2], Table.id, "Max Target RPM",true)
+ ACF_GearsSlider(10, acfmenupanel.GearboxData[Table.id].GearTable[-1], Table.id, "Final Drive")
+ RunConsoleCommand( "acfmenu_data1", 0.01 )
+ else
+ for ID,Value in pairs(acfmenupanel.GearboxData[Table.id].GearTable) do
+ if ID > 0 and not (Table.auto and ID == 8) then
+ ACF_GearsSlider(ID, Value, Table.id)
+ if Table.auto then
+ ACF_ShiftPoint(ID, acfmenupanel.GearboxData[Table.id].ShiftTable[ID], Table.id, "Gear "..ID.." upshift speed: ")
+ end
+ elseif Table.auto and (ID == -2 or ID == 8) then
+ ACF_GearsSlider(8, Value, Table.id, "Reverse")
+ elseif ID == -1 then
+ ACF_GearsSlider(10, Value, Table.id, "Final Drive")
+ end
+ end
+ end
+
+ acfmenupanel:CPanelText("Desc", Table.desc)
+ acfmenupanel:CPanelText("MaxTorque", "Clutch Maximum Torque Rating : "..(Table.maxtq).."n-m / "..math.Round(Table.maxtq*0.73).."ft-lb")
+ acfmenupanel:CPanelText("Weight", "Weight : "..Table.weight.."kg")
+
+ if Table.parentable then
+ acfmenupanel:CPanelText("Parentable", "\nThis gearbox can be parented without welding.")
+ end
+
+ if Table.auto then
+ acfmenupanel:CPanelText( "ShiftPointGen", "\nShift Point Generator:" )
+
+ if not acfmenupanel.CData.ShiftGenPanel then
+ acfmenupanel.CData.ShiftGenPanel = vgui.Create( "DPanel" )
+ acfmenupanel.CData.ShiftGenPanel:SetPaintBackground( false )
+ acfmenupanel.CData.ShiftGenPanel:DockPadding( 4, 0, 4, 0 )
+ acfmenupanel.CData.ShiftGenPanel:SetTall( 60 )
+ acfmenupanel.CData.ShiftGenPanel:SizeToContentsX()
+ acfmenupanel.CData.ShiftGenPanel.Gears = Table.gears
+
+ acfmenupanel.CData.ShiftGenPanel.Calc = acfmenupanel.CData.ShiftGenPanel:Add( "DButton" )
+ acfmenupanel.CData.ShiftGenPanel.Calc:SetText( "Calculate" )
+ acfmenupanel.CData.ShiftGenPanel.Calc:Dock( BOTTOM )
+ --acfmenupanel.CData.ShiftGenPanel.Calc:SetWide( 80 )
+ acfmenupanel.CData.ShiftGenPanel.Calc:SetTall( 20 )
+ acfmenupanel.CData.ShiftGenPanel.Calc.DoClick = function()
+ local str, factor = acfmenupanel.CData.UnitsInput:GetSelected()
+ local mul = math.pi * acfmenupanel.CData.ShiftGenPanel.RPM:GetValue() * acfmenupanel.CData.ShiftGenPanel.Ratio:GetValue() * acfmenupanel.CData[10]:GetValue() * acfmenupanel.CData.ShiftGenPanel.Wheel:GetValue() / (60 * factor)
+ for i=1,acfmenupanel.CData.ShiftGenPanel.Gears do
+ acfmenupanel.CData[10+i].Input:SetValue( math.Round( math.abs( mul * acfmenupanel.CData[i]:GetValue() ), 2 ) )
+ acfmenupanel.GearboxData[acfmenupanel.CData.UnitsInput.ID].ShiftTable[i] = tonumber(acfmenupanel.CData[10+i].Input:GetValue())
+ end
+ acfmenupanel.Serialize( acfmenupanel.GearboxData[acfmenupanel.CData.UnitsInput.ID].ShiftTable, factor ) --dot intentional
+ end
+
+ acfmenupanel.CData.WheelPanel = acfmenupanel.CData.ShiftGenPanel:Add( "DPanel" )
+ acfmenupanel.CData.WheelPanel:SetPaintBackground( false )
+ acfmenupanel.CData.WheelPanel:DockMargin( 4, 0, 4, 0 )
+ acfmenupanel.CData.WheelPanel:Dock( RIGHT )
+ acfmenupanel.CData.WheelPanel:SetWide( 76 )
+ acfmenupanel.CData.WheelPanel:SetTooltip( "If you use default spherical settings, add 0.5 to your wheel diameter.\nFor treaded vehicles, use the diameter of road wheels, not drive wheels." )
+
+ acfmenupanel.CData.ShiftGenPanel.WheelLabel = acfmenupanel.CData.WheelPanel:Add( "DLabel" )
+ acfmenupanel.CData.ShiftGenPanel.WheelLabel:Dock( TOP )
+ acfmenupanel.CData.ShiftGenPanel.WheelLabel:SetDark( true )
+ acfmenupanel.CData.ShiftGenPanel.WheelLabel:SetText( "Wheel Diameter:" )
+
+ acfmenupanel.CData.ShiftGenPanel.Wheel = acfmenupanel.CData.WheelPanel:Add( "DNumberWang" )
+ acfmenupanel.CData.ShiftGenPanel.Wheel:HideWang()
+ acfmenupanel.CData.ShiftGenPanel.Wheel:SetDrawBorder( false )
+ acfmenupanel.CData.ShiftGenPanel.Wheel:Dock( BOTTOM )
+ acfmenupanel.CData.ShiftGenPanel.Wheel:SetDecimals( 2 )
+ acfmenupanel.CData.ShiftGenPanel.Wheel:SetMinMax( 0, 9999 )
+ acfmenupanel.CData.ShiftGenPanel.Wheel:SetValue( 30 )
+
+ acfmenupanel.CData.RatioPanel = acfmenupanel.CData.ShiftGenPanel:Add( "DPanel" )
+ acfmenupanel.CData.RatioPanel:SetPaintBackground( false )
+ acfmenupanel.CData.RatioPanel:DockMargin( 4, 0, 4, 0 )
+ acfmenupanel.CData.RatioPanel:Dock( RIGHT )
+ acfmenupanel.CData.RatioPanel:SetWide( 76 )
+ acfmenupanel.CData.RatioPanel:SetTooltip( "Total ratio is the ratio of all gearboxes (exluding this one) multiplied together.\nFor example, if you use engine to automatic to diffs to wheels, your total ratio would be (diff gear ratio * diff final ratio)." )
+
+ acfmenupanel.CData.ShiftGenPanel.RatioLabel = acfmenupanel.CData.RatioPanel:Add( "DLabel" )
+ acfmenupanel.CData.ShiftGenPanel.RatioLabel:Dock( TOP )
+ acfmenupanel.CData.ShiftGenPanel.RatioLabel:SetDark( true )
+ acfmenupanel.CData.ShiftGenPanel.RatioLabel:SetText( "Total ratio:" )
+
+ acfmenupanel.CData.ShiftGenPanel.Ratio = acfmenupanel.CData.RatioPanel:Add( "DNumberWang" )
+ acfmenupanel.CData.ShiftGenPanel.Ratio:HideWang()
+ acfmenupanel.CData.ShiftGenPanel.Ratio:SetDrawBorder( false )
+ acfmenupanel.CData.ShiftGenPanel.Ratio:Dock( BOTTOM )
+ acfmenupanel.CData.ShiftGenPanel.Ratio:SetDecimals( 2 )
+ acfmenupanel.CData.ShiftGenPanel.Ratio:SetMinMax( 0, 9999 )
+ acfmenupanel.CData.ShiftGenPanel.Ratio:SetValue( 0.1 )
+
+ acfmenupanel.CData.RPMPanel = acfmenupanel.CData.ShiftGenPanel:Add( "DPanel" )
+ acfmenupanel.CData.RPMPanel:SetPaintBackground( false )
+ acfmenupanel.CData.RPMPanel:DockMargin( 4, 0, 4, 0 )
+ acfmenupanel.CData.RPMPanel:Dock( RIGHT )
+ acfmenupanel.CData.RPMPanel:SetWide( 76 )
+ acfmenupanel.CData.RPMPanel:SetTooltip( "Target engine RPM to upshift at." )
+
+ acfmenupanel.CData.ShiftGenPanel.RPMLabel = acfmenupanel.CData.RPMPanel:Add( "DLabel" )
+ acfmenupanel.CData.ShiftGenPanel.RPMLabel:Dock( TOP )
+ acfmenupanel.CData.ShiftGenPanel.RPMLabel:SetDark( true )
+ acfmenupanel.CData.ShiftGenPanel.RPMLabel:SetText( "Upshift RPM:" )
+
+ acfmenupanel.CData.ShiftGenPanel.RPM = acfmenupanel.CData.RPMPanel:Add( "DNumberWang" )
+ acfmenupanel.CData.ShiftGenPanel.RPM:HideWang()
+ acfmenupanel.CData.ShiftGenPanel.RPM:SetDrawBorder( false )
+ acfmenupanel.CData.ShiftGenPanel.RPM:Dock( BOTTOM )
+ acfmenupanel.CData.ShiftGenPanel.RPM:SetDecimals( 2 )
+ acfmenupanel.CData.ShiftGenPanel.RPM:SetMinMax( 0, 9999 )
+ acfmenupanel.CData.ShiftGenPanel.RPM:SetValue( 5000 )
+
+ acfmenupanel.CustomDisplay:AddItem(acfmenupanel.CData.ShiftGenPanel)
+ end
+ end
+
+ acfmenupanel.CustomDisplay:PerformLayout()
+ maxtorque = Table.maxtq
+ end
+
+ function ACF_GearsSlider(Gear, Value, ID, Desc, CVT)
+
+ if Gear and not acfmenupanel.CData[Gear] then
+ acfmenupanel.CData[Gear] = vgui.Create( "DNumSlider", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData[Gear]:SetText( Desc or "Gear "..Gear )
+ acfmenupanel.CData[Gear].Label:SizeToContents()
+ acfmenupanel.CData[Gear]:SetDark( true )
+ acfmenupanel.CData[Gear]:SetMin( CVT and 1 or -1 )
+ acfmenupanel.CData[Gear]:SetMax( CVT and 10000 or 1 )
+ acfmenupanel.CData[Gear]:SetDecimals( (not CVT) and 2 or 0 )
+ acfmenupanel.CData[Gear].Gear = Gear
+ acfmenupanel.CData[Gear].ID = ID
+ acfmenupanel.CData[Gear]:SetValue(Value)
+ RunConsoleCommand( "acfmenu_data"..Gear, Value )
+ acfmenupanel.CData[Gear].OnValueChanged = function( slider, val )
+ acfmenupanel.GearboxData[slider.ID].GearTable[slider.Gear] = val
+ RunConsoleCommand( "acfmenu_data"..Gear, val )
+ end
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData[Gear] )
+ end
+
+ end
+
+ function ACF_ShiftPoint(Gear, Value, ID, Desc)
+ local Index = Gear + 10
+ if Gear and not acfmenupanel.CData[Index] then
+ acfmenupanel.CData[Index] = vgui.Create( "DPanel" )
+ acfmenupanel.CData[Index]:SetPaintBackground( false )
+ acfmenupanel.CData[Index]:SetTall( 20 )
+ acfmenupanel.CData[Index]:SizeToContentsX()
+
+ acfmenupanel.CData[Index].Input = acfmenupanel.CData[Index]:Add( "DNumberWang" )
+ acfmenupanel.CData[Index].Input.Gear = Gear
+ acfmenupanel.CData[Index].Input.ID = ID
+ acfmenupanel.CData[Index].Input:HideWang()
+ acfmenupanel.CData[Index].Input:SetDrawBorder( false )
+ acfmenupanel.CData[Index].Input:SetDecimals( 2 )
+ acfmenupanel.CData[Index].Input:SetMinMax( 0, 9999 )
+ acfmenupanel.CData[Index].Input:SetValue( Value )
+ acfmenupanel.CData[Index].Input:Dock( RIGHT )
+ acfmenupanel.CData[Index].Input:SetWide( 45 )
+ acfmenupanel.CData[Index].Input.OnValueChanged = function( box, value )
+ acfmenupanel.GearboxData[box.ID].ShiftTable[box.Gear] = value
+ local str, factor = acfmenupanel.CData.UnitsInput:GetSelected()
+ acfmenupanel.Serialize( acfmenupanel.GearboxData[acfmenupanel.CData.UnitsInput.ID].ShiftTable, factor ) --dot intentional
+ end
+ RunConsoleCommand( "acfmenu_data9", "10,20,30,40,50,60,70" )
+
+ acfmenupanel.CData[Index].Label = acfmenupanel.CData[Index]:Add( "DLabel" )
+ acfmenupanel.CData[Index].Label:Dock( RIGHT )
+ acfmenupanel.CData[Index].Label:SetWide( 120 )
+ acfmenupanel.CData[Index].Label:SetDark( true )
+ acfmenupanel.CData[Index].Label:SetText( Desc )
+
+ acfmenupanel.CustomDisplay:AddItem(acfmenupanel.CData[Index])
+ end
+ end
+
+ return
+
+end
+
+function ENT:Initialize()
+
+ self.IsGeartrain = true
+ self.Master = {}
+ self.IsMaster = true
+
+ self.WheelLink = {} -- a "Link" has these components: Ent, Side, Axis, Rope, RopeLen, Output, ReqTq, Vel
+
+ self.TotalReqTq = 0
+ self.RClutch = 0
+ self.LClutch = 0
+ self.LBrake = 0
+ self.RBrake = 0
+ self.SteerRate = 0
+
+ self.Gear = 0
+ self.GearRatio = 0
+ self.ChangeFinished = 0
+
+ self.LegalThink = 0
+
+ self.RPM = {}
+ self.CurRPM = 0
+ self.CVT = false
+ self.DoubleDiff = false
+ self.Auto = false
+ self.InGear = false
+ self.CanUpdate = true
+ self.LastActive = 0
+ self.Legal = true
+ self.Parentable = true
+ self.RootParent = nil
+ self.NextLegalCheck = ACF.CurTime + 30 -- give any spawning issues time to iron themselves out
+ self.LegalIssues = ""
+
+end
+
+function MakeACF_Gearbox(Owner, Pos, Angle, Id, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Data9, Data10)
+
+ if not Owner:CheckLimit("_acf_misc") then return false end
+
+ local Gearbox = ents.Create("acf_gearbox")
+ local List = list.Get("ACFEnts")
+ local Classes = list.Get("ACFClasses")
+ if not IsValid( Gearbox ) then return false end
+ Gearbox:SetAngles(Angle)
+ Gearbox:SetPos(Pos)
+ Gearbox:Spawn()
+
+ Gearbox:SetPlayer(Owner)
+ Gearbox.Owner = Owner
+ Gearbox.Id = Id
+ Gearbox.Model = List.Mobility[Id].model
+ Gearbox.Mass = List.Mobility[Id].weight
+ Gearbox.SwitchTime = List.Mobility[Id].switch
+ Gearbox.MaxTorque = List.Mobility[Id].maxtq
+ Gearbox.Gears = List.Mobility[Id].gears
+ Gearbox.Dual = List.Mobility[Id].doubleclutch or false
+ Gearbox.CVT = List.Mobility[Id].cvt or false
+ Gearbox.DoubleDiff = List.Mobility[Id].doublediff or false
+ Gearbox.Auto = List.Mobility[Id].auto or false
+ Gearbox.Parentable = List.Mobility[Id].parentable or false
+
+ if Gearbox.CVT then
+ Gearbox.TargetMinRPM = Data3
+ Gearbox.TargetMaxRPM = math.max(Data4,Data3+100)
+ Gearbox.CVTRatio = nil
+ end
+
+ Gearbox.GearTable = List.Mobility[Id].geartable
+ Gearbox.GearTable.Final = Data10
+ Gearbox.GearTable[1] = Data1
+ Gearbox.GearTable[2] = Data2
+ Gearbox.GearTable[3] = Data3
+ Gearbox.GearTable[4] = Data4
+ Gearbox.GearTable[5] = Data5
+ Gearbox.GearTable[6] = Data6
+ Gearbox.GearTable[7] = Data7
+ Gearbox.GearTable[8] = Data8
+ Gearbox.GearTable[9] = Data9
+ Gearbox.GearTable[0] = List.Mobility[Id].geartable[0]
+
+ Gearbox.Gear0 = Data10
+ Gearbox.Gear1 = Data1
+ Gearbox.Gear2 = Data2
+ Gearbox.Gear3 = Data3
+ Gearbox.Gear4 = Data4
+ Gearbox.Gear5 = Data5
+ Gearbox.Gear6 = Data6
+ Gearbox.Gear7 = Data7
+ Gearbox.Gear8 = Data8
+ Gearbox.Gear9 = Data9
+
+ Gearbox.GearRatio = (Gearbox.GearTable[0] or 0)*Gearbox.GearTable.Final
+
+ if Gearbox.Auto then
+ Gearbox.ShiftPoints = {}
+ for part in string.gmatch(Data9, "[^,]+") do Gearbox.ShiftPoints[#Gearbox.ShiftPoints+1] = tonumber(part) end
+ Gearbox.ShiftPoints[0] = -1
+ Gearbox.Reverse = Gearbox.Gears+1
+ Gearbox.GearTable[Gearbox.Reverse] = Data8
+ Gearbox.Drive = 1
+ Gearbox.ShiftScale = 1
+ end
+
+ Gearbox:SetModel( Gearbox.Model )
+
+ local Inputs = {"Gear","Gear Up","Gear Down"}
+ if Gearbox.CVT then
+ table.insert(Inputs,"CVT Ratio")
+ elseif Gearbox.DoubleDiff then
+ table.insert(Inputs, "Steer Rate")
+ elseif Gearbox.Auto then
+ table.insert(Inputs, "Hold Gear")
+ table.insert(Inputs, "Shift Speed Scale")
+ Gearbox.Hold = false
+ end
+
+ if Gearbox.Dual then
+ table.insert(Inputs, "Left Clutch")
+ table.insert(Inputs, "Right Clutch")
+ table.insert(Inputs, "Left Brake")
+ table.insert(Inputs, "Right Brake")
+ else
+ table.insert(Inputs, "Clutch")
+ table.insert(Inputs, "Brake")
+ end
+
+ local Outputs = { "Ratio", "Entity", "Current Gear" }
+ local OutputTypes = { "NORMAL", "ENTITY", "NORMAL" }
+ if Gearbox.CVT then
+ table.insert(Outputs,"Min Target RPM")
+ table.insert(Outputs,"Max Target RPM")
+ table.insert(OutputTypes,"NORMAL")
+ end
+
+ Gearbox.Inputs = Wire_CreateInputs( Gearbox, Inputs )
+ Gearbox.Outputs = WireLib.CreateSpecialOutputs( Gearbox, Outputs, OutputTypes )
+ Wire_TriggerOutput(Gearbox, "Entity", Gearbox)
+
+ if Gearbox.CVT then
+ Wire_TriggerOutput(Gearbox, "Min Target RPM", Gearbox.TargetMinRPM)
+ Wire_TriggerOutput(Gearbox, "Max Target RPM", Gearbox.TargetMaxRPM)
+ end
+
+ Gearbox.LClutch = Gearbox.MaxTorque
+ Gearbox.RClutch = Gearbox.MaxTorque
+
+ Gearbox:PhysicsInit( SOLID_VPHYSICS )
+ Gearbox:SetMoveType( MOVETYPE_VPHYSICS )
+ Gearbox:SetSolid( SOLID_VPHYSICS )
+
+ local phys = Gearbox:GetPhysicsObject()
+ if IsValid( phys ) then
+ phys:SetMass( Gearbox.Mass )
+ Gearbox.ModelInertia = 0.99 * phys:GetInertia()/phys:GetMass() -- giving a little wiggle room
+ end
+
+ Gearbox.In = Gearbox:WorldToLocal(Gearbox:GetAttachment(Gearbox:LookupAttachment( "input" )).Pos)
+ Gearbox.OutL = Gearbox:WorldToLocal(Gearbox:GetAttachment(Gearbox:LookupAttachment( "driveshaftL" )).Pos)
+ Gearbox.OutR = Gearbox:WorldToLocal(Gearbox:GetAttachment(Gearbox:LookupAttachment( "driveshaftR" )).Pos)
+
+ Owner:AddCount("_acf_misc", Gearbox)
+ Owner:AddCleanup( "acfmenu", Gearbox )
+
+ Gearbox:ChangeGear(1)
+
+ if Gearbox.Dual or Gearbox.DoubleDiff then
+ Gearbox:SetBodygroup(1, 1)
+ else
+ Gearbox:SetBodygroup(1, 0)
+ end
+
+ Gearbox:SetNWString( "WireName", List.Mobility[Id].name )
+ Gearbox:UpdateOverlayText()
+
+ ACF_Activate( Gearbox, 0 )
+
+ return Gearbox
+end
+list.Set( "ACFCvars", "acf_gearbox", {"id", "data1", "data2", "data3", "data4", "data5", "data6", "data7", "data8", "data9", "data10"} )
+duplicator.RegisterEntityClass("acf_gearbox", MakeACF_Gearbox, "Pos", "Angle", "Id", "Gear1", "Gear2", "Gear3", "Gear4", "Gear5", "Gear6", "Gear7", "Gear8", "Gear9", "Gear0" )
+
+function ENT:Update( ArgsTable )
+ -- That table is the player data, as sorted in the ACFCvars above, with player who shot,
+ -- and pos and angle of the tool trace inserted at the start
+
+ if ArgsTable[1] ~= self.Owner then -- Argtable[1] is the player that shot the tool
+ return false, "You don't own that gearbox!"
+ end
+
+ local Id = ArgsTable[4] -- Argtable[4] is the engine ID
+ local List = list.Get("ACFEnts")
+
+ if List.Mobility[Id].model ~= self.Model then
+ return false, "The new gearbox must have the same model!"
+ end
+
+ if self.Id != Id then
+
+ self.Id = Id
+ self.Mass = List.Mobility[Id].weight
+ self.SwitchTime = List.Mobility[Id].switch
+ self.MaxTorque = List.Mobility[Id].maxtq
+ self.Gears = List.Mobility[Id].gears
+ self.Dual = List.Mobility[Id].doubleclutch or false
+ self.CVT = List.Mobility[Id].cvt or false
+ self.DoubleDiff = List.Mobility[Id].doublediff or false
+ self.Auto = List.Mobility[Id].auto or false
+ self.Parentable = List.Mobility[Id].parentable or false
+
+ local Inputs = {"Gear","Gear Up","Gear Down"}
+ if self.CVT then
+ table.insert(Inputs,"CVT Ratio")
+ elseif self.DoubleDiff then
+ table.insert(Inputs, "Steer Rate")
+ elseif self.Auto then
+ table.insert(Inputs, "Hold Gear")
+ table.insert(Inputs, "Shift Speed Scale")
+ self.Hold = false
+ end
+
+ if self.Dual then
+ table.insert(Inputs, "Left Clutch")
+ table.insert(Inputs, "Right Clutch")
+ table.insert(Inputs, "Left Brake")
+ table.insert(Inputs, "Right Brake")
+ else
+ table.insert(Inputs, "Clutch")
+ table.insert(Inputs, "Brake")
+ end
+
+ local Outputs = { "Ratio", "Entity", "Current Gear" }
+ local OutputTypes = { "NORMAL", "ENTITY", "NORMAL" }
+ if self.CVT then
+ table.insert(Outputs,"Min Target RPM")
+ table.insert(Outputs,"Max Target RPM")
+ table.insert(OutputTypes,"NORMAL")
+ end
+
+ local phys = self:GetPhysicsObject()
+ if IsValid( phys ) then
+ phys:SetMass( self.Mass )
+ end
+
+ self.Inputs = Wire_CreateInputs( self, Inputs )
+ self.Outputs = WireLib.CreateSpecialOutputs( self, Outputs, OutputTypes )
+ Wire_TriggerOutput( self, "Entity", self )
+ end
+
+ if self.CVT then
+ self.TargetMinRPM = ArgsTable[7]
+ self.TargetMaxRPM = math.max(ArgsTable[8],ArgsTable[7]+100)
+ self.CVTRatio = nil
+ Wire_TriggerOutput(self, "Min Target RPM", self.TargetMinRPM)
+ Wire_TriggerOutput(self, "Max Target RPM", self.TargetMaxRPM)
+ end
+
+ self.GearTable.Final = ArgsTable[14]
+ self.GearTable[1] = ArgsTable[5]
+ self.GearTable[2] = ArgsTable[6]
+ self.GearTable[3] = ArgsTable[7]
+ self.GearTable[4] = ArgsTable[8]
+ self.GearTable[5] = ArgsTable[9]
+ self.GearTable[6] = ArgsTable[10]
+ self.GearTable[7] = ArgsTable[11]
+ self.GearTable[8] = ArgsTable[12]
+ self.GearTable[9] = ArgsTable[13]
+ self.GearTable[0] = List.Mobility[Id].geartable[0]
+
+ self.Gear0 = ArgsTable[14]
+ self.Gear1 = ArgsTable[5]
+ self.Gear2 = ArgsTable[6]
+ self.Gear3 = ArgsTable[7]
+ self.Gear4 = ArgsTable[8]
+ self.Gear5 = ArgsTable[9]
+ self.Gear6 = ArgsTable[10]
+ self.Gear7 = ArgsTable[11]
+ self.Gear8 = ArgsTable[12]
+ self.Gear9 = ArgsTable[13]
+
+ self.GearRatio = (self.GearTable[0] or 0)*self.GearTable.Final
+
+ if self.Auto then
+ self.ShiftPoints = {}
+ for part in string.gmatch(ArgsTable[13], "[^,]+") do self.ShiftPoints[#self.ShiftPoints+1] = tonumber(part) end
+ self.ShiftPoints[0] = -1
+ self.Reverse = self.Gears+1
+ self.GearTable[self.Reverse] = ArgsTable[12]
+ self.Drive = 1
+ self.ShiftScale = 1
+ end
+
+ --self:ChangeGear(1) -- fails on updating because func exits on detecting same gear
+ self.Gear = 1
+ self.GearRatio = (self.GearTable[self.Gear] or 0)*self.GearTable.Final
+ self.ChangeFinished = CurTime() + self.SwitchTime
+ self.InGear = false
+
+ if self.Dual or self.DoubleDiff then
+ self:SetBodygroup(1, 1)
+ else
+ self:SetBodygroup(1, 0)
+ end
+
+ self:SetNWString( "WireName", List.Mobility[Id].name )
+ self:UpdateOverlayText()
+
+ ACF_Activate( self, 1 )
+
+ return true, "Gearbox updated successfully!"
+end
+
+function ENT:UpdateOverlayText()
+
+ local text = ""
+
+ if self.CVT then
+ text = "Reverse Gear: " .. math.Round( self.GearTable[ 2 ], 2 ) -- maybe a better name than "gear 2"...?
+ text = text .. "\nTarget: " .. math.Round( self.TargetMinRPM ) .. " - " .. math.Round( self.TargetMaxRPM ) .. " RPM\n"
+ elseif self.Auto then
+ for i = 1, self.Gears do
+ text = text .. "Gear " .. i .. ": " .. math.Round( self.GearTable[ i ], 2 ) .. ", Upshift @ ".. math.Round( self.ShiftPoints[i]/10.936, 1 ) .. " kph / " .. math.Round( self.ShiftPoints[i]/17.6 ,1 ) .. " mph\n"
+ end
+ else
+ for i = 1, self.Gears do
+ text = text .. "Gear " .. i .. ": " .. math.Round( self.GearTable[ i ], 2 ) .. "\n"
+ end
+ end
+ if self.Auto then
+ text = text.."Reverse gear: "..math.Round( self.GearTable[ self.Reverse ], 2 ).."\n"
+ end
+
+ text = text .. "Final Drive: " .. math.Round( self.Gear0, 2 ) .. "\n"
+ text = text .. "Torque Rating: " .. self.MaxTorque .. " Nm / " .. math.Round( self.MaxTorque * 0.73 ) .. " ft-lb"
+
+ if not self.Legal then
+ text = text .. "\nNot legal, disabled for " .. math.ceil(self.NextLegalCheck - ACF.CurTime) .. "s\nIssues: " .. self.LegalIssues
+ end
+
+ self:SetOverlayText( text )
+
+end
+
+
+-- prevent people from changing bodygroup
+function ENT:CanProperty( ply, property )
+
+ return property ~= "bodygroups"
+
+end
+
+function ENT:TriggerInput( iname, value )
+
+ if ( iname == "Gear" ) then
+ if self.Auto then
+ self:ChangeDrive(value)
+ else
+ self:ChangeGear(value)
+ end
+ elseif ( iname == "Gear Up" ) and not (value == 0) then
+ if self.Auto then
+ self:ChangeDrive(self.Drive + 1)
+ else
+ self:ChangeGear(self.Gear + 1)
+ end
+ elseif ( iname == "Gear Down" ) and not (value == 0) then
+ if self.Auto then
+ self:ChangeDrive(self.Drive - 1)
+ else
+ self:ChangeGear(self.Gear - 1)
+ end
+ elseif ( iname == "Clutch" ) then
+ self.LClutch = math.Clamp(1-value,0,1)*self.MaxTorque
+ self.RClutch = math.Clamp(1-value,0,1)*self.MaxTorque
+ elseif ( iname == "Brake" ) then
+ self.LBrake = math.Clamp(value,0,100)
+ self.RBrake = math.Clamp(value,0,100)
+ elseif ( iname == "Left Brake" ) then
+ self.LBrake = math.Clamp(value,0,100)
+ elseif ( iname == "Right Brake" ) then
+ self.RBrake = math.Clamp(value,0,100)
+ elseif ( iname == "Left Clutch" ) then
+ self.LClutch = math.Clamp(1-value,0,1)*self.MaxTorque
+ elseif ( iname == "Right Clutch" ) then
+ self.RClutch = math.Clamp(1-value,0,1)*self.MaxTorque
+ elseif ( iname == "CVT Ratio" ) then
+ self.CVTRatio = math.Clamp(value,0,1)
+ elseif ( iname == "Steer Rate" ) then
+ self.SteerRate = math.Clamp(value,-1,1)
+ elseif ( iname == "Hold Gear" ) then
+ self.Hold = not (value == 0)
+ elseif ( iname == "Shift Speed Scale" ) then
+ self.ShiftScale = math.Clamp(value,0.1,1.5)
+ end
+
+end
+
+function ENT:Think()
+
+ if ACF.CurTime > self.NextLegalCheck then
+ self.Legal, self.LegalIssues = ACF_CheckLegal(self, self.Model, self.Mass, self.ModelInertia, false, true, false, true) --
+ self.NextLegalCheck = ACF.LegalSettings:NextCheck(self.Legal)
+ self:UpdateOverlayText()
+
+ if self.Legal then
+ if self.Parentable then self.RootParent = ACF_GetPhysicalParent(self) end
+ end
+ end
+
+ local Time = CurTime()
+
+ if self.LastActive + 2 > Time then
+ self:CheckRopes()
+ end
+
+ self:NextThink( Time + math.random( 5, 10 ) )
+ return true
+
+end
+
+function ENT:CheckRopes()
+
+ for Key, Link in pairs( self.WheelLink ) do
+
+ local Ent = Link.Ent
+
+ local OutPos = self:LocalToWorld( Link.Output )
+ local InPos = Ent:GetPos()
+ if Ent.IsGeartrain then
+ InPos = Ent:LocalToWorld( Ent.In )
+ end
+
+ -- make sure it is not stretched too far
+ if OutPos:Distance( InPos ) > Link.RopeLen * 1.5 then
+ self:Unlink( Ent )
+ end
+
+ -- make sure the angle is not excessive
+ local DrvAngle = ( OutPos - InPos ):GetNormalized():DotProduct( ( self:GetRight() * Link.Output.y ):GetNormalized() )
+ if DrvAngle < 0.7 then
+ self:Unlink( Ent )
+ end
+
+ end
+
+end
+
+-- Check if every entity we are linked to still actually exists
+-- and remove any links that are invalid.
+function ENT:CheckEnts()
+
+ for Key, Link in pairs( self.WheelLink ) do
+
+ if not IsValid( Link.Ent ) then
+ table.remove( self.WheelLink, Key )
+ continue end
+
+ local Phys = Link.Ent:GetPhysicsObject()
+ if not IsValid( Phys ) then
+ Link.Ent:Remove()
+ table.remove( self.WheelLink, Key )
+ end
+
+ end
+
+end
+
+function ENT:Calc( InputRPM, InputInertia )
+
+ if not self.Legal then return 0 end
+
+ if self.LastActive == CurTime() then
+ return math.min( self.TotalReqTq, self.MaxTorque )
+ end
+
+ if self.ChangeFinished < CurTime() then
+ self.InGear = true
+ end
+
+ self:CheckEnts()
+
+ local BoxPhys = self:GetPhysicsObject()
+ local SelfWorld = BoxPhys:LocalToWorldVector( BoxPhys:GetAngleVelocity() )
+
+ if self.CVT and self.Gear == 1 then
+ if self.CVTRatio and self.CVTRatio > 0 then
+ self.GearTable[1] = math.Clamp(self.CVTRatio,0.01,1)
+ else
+ self.GearTable[1] = math.Clamp((InputRPM - self.TargetMinRPM) / ((self.TargetMaxRPM - self.TargetMinRPM) or 1),0.05,1)
+ end
+ self.GearRatio = (self.GearTable[1] or 0)*self.GearTable.Final
+ Wire_TriggerOutput(self, "Ratio", self.GearRatio)
+ end
+
+ if self.Auto and self.Drive == 1 and self.InGear then
+ local vel = BoxPhys:GetVelocity():Length()
+ if vel > (self.ShiftPoints[self.Gear] * self.ShiftScale) and not (self.Gear == self.Gears) and not self.Hold then
+ self:ChangeGear(self.Gear + 1)
+ elseif vel < (self.ShiftPoints[self.Gear-1] * self.ShiftScale) then
+ self:ChangeGear(self.Gear - 1)
+ end
+ end
+
+ self.TotalReqTq = 0
+
+ for Key, Link in pairs( self.WheelLink ) do
+ if not IsValid( Link.Ent ) then
+ table.remove( self.WheelLink, Key )
+ continue end
+
+ local Clutch = 0
+ if Link.Side == 0 then
+ Clutch = self.LClutch
+ elseif Link.Side == 1 then
+ Clutch = self.RClutch
+ end
+
+ Link.ReqTq = 0
+ if Link.Ent.IsGeartrain then
+ if not Link.Ent.Legal then continue end
+ local Inertia = 0
+ if self.GearRatio ~= 0 then Inertia = InputInertia / self.GearRatio end
+ Link.ReqTq = math.min( Clutch, math.abs( Link.Ent:Calc( InputRPM * self.GearRatio, Inertia ) * self.GearRatio ) )
+ elseif self.DoubleDiff then
+ local RPM = self:CalcWheel( Link, SelfWorld )
+ if self.GearRatio ~= 0 and ( ( InputRPM > 0 and RPM < InputRPM ) or ( InputRPM < 0 and RPM > InputRPM ) ) then
+ local NTq = math.min( Clutch, ( InputRPM - RPM) * InputInertia)
+
+ if( self.SteerRate ~= 0 ) then
+ Sign = self.SteerRate / math.abs( self.SteerRate )
+ else
+ Sign = 0
+ end
+ if Link.Side == 0 then
+ local DTq = math.Clamp( ( self.SteerRate * ( ( InputRPM * ( math.abs( self.SteerRate ) + 1 ) ) - (RPM * Sign) ) ) * InputInertia, -self.MaxTorque, self.MaxTorque )
+ Link.ReqTq = ( NTq + DTq )
+ elseif Link.Side == 1 then
+ local DTq = math.Clamp( ( self.SteerRate * ( ( InputRPM * ( math.abs( self.SteerRate ) + 1 ) ) + (RPM * Sign) ) ) * InputInertia, -self.MaxTorque, self.MaxTorque )
+ Link.ReqTq = ( NTq - DTq )
+ end
+ end
+ else
+ local RPM = self:CalcWheel( Link, SelfWorld )
+ if self.GearRatio ~= 0 and ( ( InputRPM > 0 and RPM < InputRPM ) or ( InputRPM < 0 and RPM > InputRPM ) ) then
+ Link.ReqTq = math.min( Clutch, ( InputRPM - RPM ) * InputInertia )
+ end
+ end
+
+ self.TotalReqTq = self.TotalReqTq + math.abs( Link.ReqTq )
+ end
+
+ return math.min( self.TotalReqTq, self.MaxTorque )
+
+end
+
+function ENT:CalcWheel( Link, SelfWorld )
+
+ local Wheel = Link.Ent
+ local WheelPhys = Wheel:GetPhysicsObject()
+ local VelDiff = WheelPhys:LocalToWorldVector( WheelPhys:GetAngleVelocity() ) - SelfWorld
+ local BaseRPM = VelDiff:Dot( WheelPhys:LocalToWorldVector( Link.Axis ) )
+ Link.Vel = BaseRPM
+
+ if self.GearRatio == 0 then return 0 end
+
+ -- Reported BaseRPM is in angle per second and in the wrong direction, so we convert and add the gearratio
+ return BaseRPM / self.GearRatio / -6
+
+end
+
+function ENT:Act( Torque, DeltaTime, MassRatio )
+ if not self.Legal then self.LastActive = CurTime() return end
+
+ --internal torque loss from being damaged
+ local Loss = math.Clamp(((1 - 0.4) / (0.5)) * ((self.ACF.Health/self.ACF.MaxHealth) - 1) + 1, 0.4, 1)
+
+ --internal torque loss from inefficiency
+ local Slop = self.Auto and 0.9 or 1
+
+ local ReactTq = 0
+ -- Calculate the ratio of total requested torque versus what's avaliable, and then multiply it but the current gearratio
+ local AvailTq = 0
+ if Torque ~= 0 and self.GearRatio ~= 0 then
+ AvailTq = math.min( math.abs( Torque ) / self.TotalReqTq, 1 ) / self.GearRatio * -( -Torque / math.abs( Torque ) ) * Loss * Slop
+ end
+
+ for Key, Link in pairs( self.WheelLink ) do
+
+ local Brake = 0
+ if Link.Side == 0 then
+ Brake = self.LBrake
+ elseif Link.Side == 1 then
+ Brake = self.RBrake
+ end
+
+ if Link.Ent.IsGeartrain then
+ Link.Ent:Act( Link.ReqTq * AvailTq, DeltaTime, MassRatio )
+ else
+ self:ActWheel( Link, Link.ReqTq * AvailTq, Brake, DeltaTime )
+ ReactTq = ReactTq + Link.ReqTq * AvailTq
+ end
+
+ end
+
+ local BoxPhys
+ if IsValid( self.RootParent ) then
+ BoxPhys = self.RootParent:GetPhysicsObject()
+ else
+ BoxPhys = self:GetPhysicsObject()
+ end
+
+ if IsValid( BoxPhys ) and ReactTq ~= 0 then
+ local Torque = self:GetRight() * math.Clamp( 2 * math.deg( ReactTq * MassRatio ) * DeltaTime, -500000, 500000 )
+ BoxPhys:ApplyTorqueCenter( Torque )
+ end
+
+ self.LastActive = CurTime()
+
+end
+
+function ENT:ActWheel( Link, Torque, Brake, DeltaTime )
+
+ local Phys = Link.Ent:GetPhysicsObject()
+ local TorqueAxis = Phys:LocalToWorldVector( Link.Axis )
+
+ local BrakeMult = 0
+ if Brake > 0 then
+ BrakeMult = Link.Vel * Link.Inertia * Brake / 5
+ end
+
+ local Torque = TorqueAxis * math.Clamp( math.deg( -Torque * 1.5 - BrakeMult ) * DeltaTime, -500000, 500000 )
+ Phys:ApplyTorqueCenter( Torque )
+end
+
+function ENT:ChangeGear(value)
+
+ local new = math.Clamp(math.floor(value),0,self.Gears)
+ if self.Gear == new then return end
+
+ self.Gear = new
+ self.GearRatio = (self.GearTable[self.Gear] or 0)*self.GearTable.Final
+ self.ChangeFinished = CurTime() + self.SwitchTime
+ self.InGear = false
+
+ Wire_TriggerOutput(self, "Current Gear", self.Gear)
+ self:EmitSound("buttons/lever7.wav",250,100)
+ Wire_TriggerOutput(self, "Ratio", self.GearRatio)
+
+end
+
+--handles gearing for automatics; 0=neutral, 1=forward autogearing, 2=reverse
+function ENT:ChangeDrive(value)
+
+ local new = math.Clamp(math.floor(value),0,2)
+ if self.Drive == new then return end
+
+ self.Drive = new
+ if self.Drive == 2 then
+ self.Gear = self.Reverse
+ self.GearRatio = (self.GearTable[self.Gear] or 0)*self.GearTable.Final
+ self.ChangeFinished = CurTime() + self.SwitchTime
+ self.InGear = false
+
+ Wire_TriggerOutput(self, "Current Gear", self.Gear)
+ self:EmitSound("buttons/lever7.wav",250,100)
+ Wire_TriggerOutput(self, "Ratio", self.GearRatio)
+ else
+ self:ChangeGear(self.Drive) --autogearing in :calc will set correct gear
+ end
+
+end
+
+function ENT:Link( Target )
+
+ if not IsValid( Target ) or not table.HasValue( { "prop_physics", "acf_gearbox", "tire" }, Target:GetClass() ) then
+ return false, "Can only link props or gearboxes!"
+ end
+
+ -- Check if target is already linked
+ for Key, Link in pairs( self.WheelLink ) do
+ if Link.Ent == Target then
+ return false, "That is already linked to this gearbox!"
+ end
+ end
+
+ -- make sure the angle is not excessive
+ local InPos = Vector( 0, 0, 0 )
+ if Target.IsGeartrain then
+ InPos = Target.In
+ end
+ local InPosWorld = Target:LocalToWorld( InPos )
+
+ local OutPos = self.OutR
+ local Side = 1
+ if self:WorldToLocal( InPosWorld ).y < 0 then
+ OutPos = self.OutL
+ Side = 0
+ end
+ local OutPosWorld = self:LocalToWorld( OutPos )
+
+ local DrvAngle = ( OutPosWorld - InPosWorld ):GetNormalized():DotProduct( ( self:GetRight() * OutPos.y ):GetNormalized() )
+ if DrvAngle < 0.7 then
+ return false, "Cannot link due to excessive driveshaft angle!"
+ end
+
+ local Rope = nil
+ if self.Owner:GetInfoNum( "ACF_MobilityRopeLinks", 1) == 1 then
+ Rope = constraint.CreateKeyframeRope( OutPosWorld, 1, "cable/cable2", nil, self, OutPos, 0, Target, InPos, 0 )
+ end
+ local Phys = Target:GetPhysicsObject()
+ local Axis = Phys:WorldToLocalVector( self:GetRight() )
+ local Inertia = ( Axis * Phys:GetInertia() ):Length()
+
+ local Link = {
+ Ent = Target,
+ Side = Side,
+ Axis = Axis,
+ Inertia = Inertia,
+ Rope = Rope,
+ RopeLen = ( OutPosWorld - InPosWorld ):Length(),
+ Output = OutPos,
+ ReqTq = 0,
+ Vel = 0
+ }
+ table.insert( self.WheelLink, Link )
+
+ return true, "Link successful!"
+
+end
+
+function ENT:Unlink( Target )
+
+ for Key, Link in pairs( self.WheelLink ) do
+
+ if Link.Ent == Target then
+
+ -- Remove any old physical ropes leftover from dupes
+ for Key, Rope in pairs( constraint.FindConstraints( Link.Ent, "Rope" ) ) do
+ if Rope.Ent1 == self or Rope.Ent2 == self then
+ Rope.Constraint:Remove()
+ end
+ end
+
+ if IsValid( Link.Rope ) then
+ Link.Rope:Remove()
+ end
+
+ table.remove( self.WheelLink, Key )
+
+ return true, "Unlink successful!"
+
+ end
+
+ end
+
+ return false, "That entity is not linked to this gearbox!"
+
+end
+
+function ENT:PreEntityCopy()
+
+ -- Link Saving
+ local info = {}
+ local entids = {}
+
+ -- Clean the table of any invalid entities
+ for Key, Link in pairs( self.WheelLink ) do
+ if not IsValid( Link.Ent ) then
+ table.remove( self.WheelLink, Key )
+ end
+ end
+
+ -- Then save it
+ for Key, Link in pairs( self.WheelLink ) do
+ table.insert( entids, Link.Ent:EntIndex() )
+ end
+
+ info.entities = entids
+ if info.entities then
+ duplicator.StoreEntityModifier( self, "WheelLink", info )
+ end
+
+ //Wire dupe info
+ self.BaseClass.PreEntityCopy( self )
+
+end
+
+function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
+
+ -- Link Pasting
+ if Ent.EntityMods and Ent.EntityMods.WheelLink and Ent.EntityMods.WheelLink.entities then
+ local WheelLink = Ent.EntityMods.WheelLink
+ if WheelLink.entities and table.Count( WheelLink.entities ) > 0 then
+ timer.Simple( 0, function() -- this timer is a workaround for an ad2/makespherical issue https://github.com/nrlulz/ACF/issues/14#issuecomment-22844064
+ for _, ID in pairs( WheelLink.entities ) do
+ local Linked = CreatedEntities[ ID ]
+ if IsValid( Linked ) then
+ self:Link( Linked )
+ end
+ end
+ end )
+ end
+ Ent.EntityMods.WheelLink = nil
+ end
+
+ //Wire dupe info
+ self.BaseClass.PostEntityPaste( self, Player, Ent, CreatedEntities )
+
+end
+
+function ENT:OnRemove()
+
+ for Key,Value in pairs(self.Master) do --Let's unlink ourselves from the engines properly
+ if IsValid( self.Master[Key] ) then
+ self.Master[Key]:Unlink( self )
+ end
+ end
+
+end
+
diff --git a/lua/entities/acf_gun.lua b/lua/entities/acf_gun.lua
new file mode 100644
index 000000000..1cebb8108
--- /dev/null
+++ b/lua/entities/acf_gun.lua
@@ -0,0 +1,856 @@
+
+AddCSLuaFile()
+
+DEFINE_BASECLASS( "base_wire_entity" )
+
+ENT.PrintName = "ACF Gun"
+ENT.WireDebugName = "ACF Gun"
+
+if CLIENT then
+
+ local ACF_GunInfoWhileSeated = CreateClientConVar("ACF_GunInfoWhileSeated", 0, true, false)
+
+ function ENT:Initialize()
+
+ self.BaseClass.Initialize( self )
+
+ self.LastFire = 0
+ self.Reload = 1
+ self.CloseTime = 1
+ self.Rate = 1
+ self.RateScale = 1
+ self.FireAnim = self:LookupSequence( "shoot" )
+ self.CloseAnim = self:LookupSequence( "load" )
+
+ end
+
+ -- copied from base_wire_entity: DoNormalDraw's notip arg isn't accessible from ENT:Draw defined there.
+ function ENT:Draw()
+
+ local lply = LocalPlayer()
+ local hideBubble = not ACF_GunInfoWhileSeated:GetBool() and IsValid(lply) and lply:InVehicle()
+
+ self.BaseClass.DoNormalDraw(self, false, hideBubble)
+ Wire_Render(self)
+
+ if self.GetBeamLength and (not self.GetShowBeam or self:GetShowBeam()) then
+ -- Every SENT that has GetBeamLength should draw a tracer. Some of them have the GetShowBeam boolean
+ Wire_DrawTracerBeam( self, 1, self.GetBeamHighlight and self:GetBeamHighlight() or false )
+ end
+
+ end
+
+ function ENT:Think()
+
+ self.BaseClass.Think( self )
+
+ local SinceFire = CurTime() - self.LastFire
+ self:SetCycle( SinceFire * self.Rate / self.RateScale )
+ if CurTime() > self.LastFire + self.CloseTime and self.CloseAnim then
+ self:ResetSequence( self.CloseAnim )
+ self:SetCycle( ( SinceFire - self.CloseTime ) * self.Rate / self.RateScale )
+ self.Rate = 1 / ( self.Reload - self.CloseTime ) -- Base anim time is 1s, rate is in 1/10 of a second
+ self:SetPlaybackRate( self.Rate )
+ end
+
+ end
+
+ function ENT:Animate( Class, ReloadTime, LoadOnly )
+
+ if self.CloseAnim and self.CloseAnim > 0 then
+ self.CloseTime = math.max(ReloadTime-0.75,ReloadTime*0.75)
+ else
+ self.CloseTime = ReloadTime
+ self.CloseAnim = nil
+ end
+
+ self:ResetSequence( self.FireAnim )
+ self:SetCycle( 0 )
+ self.RateScale = self:SequenceDuration()
+ if LoadOnly then
+ self.Rate = 1000000
+ else
+ self.Rate = 1/math.Clamp(self.CloseTime,0.1,1.5) --Base anim time is 1s, rate is in 1/10 of a second
+ end
+ self:SetPlaybackRate( self.Rate )
+ self.LastFire = CurTime()
+ self.Reload = ReloadTime
+
+ end
+
+ function ACFGunGUICreate( Table )
+
+ acfmenupanel:CPanelText("Name", Table.name)
+
+ acfmenupanel.CData.DisplayModel = vgui.Create( "DModelPanel", acfmenupanel.CustomDisplay )
+ acfmenupanel.CData.DisplayModel:SetModel( Table.model )
+ acfmenupanel.CData.DisplayModel:SetCamPos( Vector( 250, 500, 250 ) )
+ acfmenupanel.CData.DisplayModel:SetLookAt( Vector( 0, 0, 0 ) )
+ acfmenupanel.CData.DisplayModel:SetFOV( 20 )
+ acfmenupanel.CData.DisplayModel:SetSize(acfmenupanel:GetWide(),acfmenupanel:GetWide())
+ acfmenupanel.CData.DisplayModel.LayoutEntity = function( panel, entity ) end
+ acfmenupanel.CustomDisplay:AddItem( acfmenupanel.CData.DisplayModel )
+ local GunClass = list.Get("ACFClasses").GunClass[Table.gunclass]
+ acfmenupanel:CPanelText("ClassDesc", GunClass.desc)
+ acfmenupanel:CPanelText("GunDesc", Table.desc)
+ acfmenupanel:CPanelText("Caliber", "Caliber : "..(Table.caliber*10).."mm")
+ acfmenupanel:CPanelText("Weight", "Weight : "..Table.weight.."kg")
+
+ --PrintTable(Table)
+ if not Table.rack then
+ local RoundVolume = 3.1416 * (Table.caliber/2)^2 * Table.round.maxlength
+ local RoF = 60 / (((RoundVolume / 500 ) ^ 0.60 ) * GunClass.rofmod * (Table.rofmod or 1)) --class and per-gun use same var name
+ acfmenupanel:CPanelText("Firerate", "RoF : "..math.Round(RoF,1).." rounds/min")
+ if Table.magsize then acfmenupanel:CPanelText("Magazine", "Magazine : "..Table.magsize.." rounds\nReload : "..Table.magreload.." s") end
+ acfmenupanel:CPanelText("Spread", "Spread : "..GunClass.spread.." degrees")
+ end
+
+ if Table.canparent then
+ acfmenupanel:CPanelText("GunParentable", "\nThis weapon can be parented.")
+ end
+
+ acfmenupanel.CustomDisplay:PerformLayout()
+
+ end
+
+ return
+
+end
+
+function ENT:Initialize()
+
+ self.ReloadTime = 1
+ self.FirstLoad = true
+ self.Ready = true
+ self.Firing = nil
+ self.Reloading = nil
+ self.CrateBonus = 1
+ self.NextFire = 0
+ self.LastSend = 0
+ self.LastLoadDuration = 0
+ self.Owner = self
+ self.Parentable = true
+ self.NextLegalCheck = ACF.CurTime + 30 -- give any spawning issues time to iron themselves out
+ self.Legal = true
+ self.LegalIssues = ""
+
+ self.IsMaster = true --needed?
+ self.AmmoLink = {}
+ self.CurAmmo = 1
+ self.Sequence = 1
+
+ self.BulletData = {}
+ self.BulletData.Type = "Empty"
+ self.BulletData.PropMass = 0
+ self.BulletData.ProjMass = 0
+
+ self.Inaccuracy = 1
+
+ self.Inputs = Wire_CreateInputs( self, { "Fire", "Unload", "Reload" } )
+ self.Outputs = WireLib.CreateSpecialOutputs( self, { "Ready", "AmmoCount", "Entity", "Shots Left", "Fire Rate", "Muzzle Weight", "Muzzle Velocity" }, { "NORMAL", "NORMAL", "ENTITY", "NORMAL", "NORMAL", "NORMAL", "NORMAL" } )
+ Wire_TriggerOutput(self, "Entity", self)
+
+end
+
+function MakeACF_Gun(Owner, Pos, Angle, Id)
+
+ local EID
+ local List = list.Get("ACFEnts")
+ if List.Guns[Id] then EID = Id else EID = "50mmC" end
+ local Lookup = List.Guns[EID]
+
+ if Lookup.gunclass == "SL" then
+ if not Owner:CheckLimit("_acf_smokelauncher") then return false end
+ else
+ if not Owner:CheckLimit("_acf_gun") then return false end
+ end
+
+ local Gun = ents.Create("acf_gun")
+ local ClassData = list.Get("ACFClasses").GunClass[Lookup.gunclass]
+ if not Gun:IsValid() then return false end
+ Gun:SetAngles(Angle)
+ Gun:SetPos(Pos)
+ Gun:Spawn()
+
+ Gun:SetPlayer(Owner)
+ Gun.Owner = Owner
+ Gun.Id = Id
+ Gun.Caliber = Lookup.caliber
+ Gun.Model = Lookup.model
+ Gun.Mass = Lookup.weight
+ Gun.Class = Lookup.gunclass
+ Gun.Parentable = Lookup.canparent
+ if ClassData.color then
+ Gun:SetColor(Color(ClassData.color[1],ClassData.color[2],ClassData.color[3], 255))
+ end
+ Gun.PGRoFmod = 1 --per gun rof
+ if(Lookup.rofmod) then
+ Gun.PGRoFmod = math.max(0.01, Lookup.rofmod)
+ end
+ Gun.CurrentShot = 0
+ Gun.MagSize = 1
+ if(Lookup.magsize) then
+ Gun.MagSize = math.max(Gun.MagSize, Lookup.magsize)
+ else
+ Gun.Inputs = Wire_AdjustInputs( Gun, { "Fire", "Unload" } )
+ end
+ Gun.MagReload = 0
+ if(Lookup.magreload) then
+ Gun.MagReload = math.max(Gun.MagReload, Lookup.magreload)
+ end
+ Gun.MinLengthBonus = 0.75 * 3.1416*(Gun.Caliber/2)^2 * Lookup.round.maxlength
+
+ Gun:SetNWString( "WireName", Lookup.name )
+ Gun:SetNWString( "Class", Gun.Class )
+ Gun:SetNWString( "ID", Gun.Id )
+ Gun.Muzzleflash = ClassData.muzzleflash
+ Gun.RoFmod = ClassData.rofmod
+ Gun.RateOfFire = 1 --updated when gun is linked to ammo
+ Gun.Sound = ClassData.sound
+ Gun:SetNWString( "Sound", Gun.Sound )
+ Gun.Inaccuracy = ClassData.spread
+ Gun:SetModel( Gun.Model )
+
+ Gun:PhysicsInit( SOLID_VPHYSICS )
+ Gun:SetMoveType( MOVETYPE_VPHYSICS )
+ Gun:SetSolid( SOLID_VPHYSICS )
+
+ local Muzzle = Gun:GetAttachment( Gun:LookupAttachment( "muzzle" ) )
+ Gun.Muzzle = Gun:WorldToLocal(Muzzle.Pos)
+
+ local longbarrel = ClassData.longbarrel
+ if longbarrel ~= nil then
+ timer.Simple(0.25, function() --need to wait until after the property is actually set
+ if Gun:GetBodygroup( longbarrel.index ) == longbarrel.submodel then
+ local Muzzle = Gun:GetAttachment( Gun:LookupAttachment( longbarrel.newpos ) )
+ Gun.Muzzle = Gun:WorldToLocal(Muzzle.Pos)
+ end
+ end)
+ end
+
+ local phys = Gun:GetPhysicsObject()
+ if IsValid( phys ) then
+ phys:SetMass( Gun.Mass )
+ Gun.ModelInertia = 0.99 * phys:GetInertia()/phys:GetMass() -- giving a little wiggle room
+ end
+
+ Gun:UpdateOverlayText()
+
+ Owner:AddCleanup( "acfmenu", Gun )
+
+ if Lookup.gunclass == "SL" then
+ Owner:AddCount("_acf_smokelauncher", Gun)
+ else
+ Owner:AddCount("_acf_gun", Gun)
+ end
+
+ ACF_Activate(Gun, 0)
+
+ return Gun
+
+end
+list.Set( "ACFCvars", "acf_gun", {"id"} )
+duplicator.RegisterEntityClass("acf_gun", MakeACF_Gun, "Pos", "Angle", "Id")
+
+function ENT:UpdateOverlayText()
+
+ local roundType = self.BulletData.Type
+
+ if self.BulletData.Tracer and self.BulletData.Tracer > 0 then
+ roundType = roundType .. "-T"
+ end
+
+ local isEmpty = self.BulletData.Type == "Empty"
+
+ local clipLeft = isEmpty and 0 or (self.MagSize - self.CurrentShot)
+ local ammoLeft = (self.Ammo or 0) + clipLeft
+ local isReloading = not isEmpty and CurTime() < self.NextFire and (self.MagSize == 1 or (self.LastLoadDuration > self.ReloadTime))
+ local gunStatus = isReloading and "reloading" or (clipLeft .. " in gun")
+
+ --print(self.MagSize or "nil", isEmpty, clipLeft, self.CurrentShot)
+
+ --print(self.LastLoadDuration, self.ReloadTime, self.LastLoadDuration > self.ReloadTime, gunStatus)
+
+ local text = roundType .. " - " .. ammoLeft .. (ammoLeft == 1 and " shot left" or " shots left ( " .. gunStatus .. " )")
+ --[[
+ local RoundData = ACF.RoundTypes[ self.BulletData.Type ]
+
+ if RoundData and RoundData.cratetxt then
+ text = text .. "\n" .. RoundData.cratetxt( self.BulletData )
+ end
+ --]]
+ text = text .. "\nRounds Per Minute: " .. math.Round( self.RateOfFire or 0, 2 )
+
+ if not self.Legal then
+ text = text .. "\nNot legal, disabled for " .. math.ceil(self.NextLegalCheck - ACF.CurTime) .. "s\nIssues: " .. self.LegalIssues
+ end
+
+ self:SetOverlayText( text )
+
+end
+
+function ENT:Link( Target )
+
+ -- Don't link if it's not an ammo crate
+ if not IsValid( Target ) or Target:GetClass() ~= "acf_ammo" then
+ return false, "Guns can only be linked to ammo crates!"
+ end
+
+ -- Don't link if it's not the right ammo type
+ if Target.BulletData.Id ~= self.Id then
+ --if not (self.Class == "AL" and string.find(Target.BulletData.Id, "mmC", 1, true)) then --allows AL to load cannon ammo
+ return false, "Wrong ammo type!"
+ --end
+ end
+
+ -- Don't link if it's a refill crate
+ if Target.RoundType == "Refill" then
+ return false, "Refill crates cannot be linked!"
+ end
+
+ -- Don't link if it's a blacklisted round type for this gun
+ local Blacklist = ACF.AmmoBlacklist[ Target.RoundType ] or {}
+
+ if table.HasValue( Blacklist, self.Class ) then
+ return false, "That round type cannot be used with this gun!"
+ end
+
+ -- Don't link if it's already linked
+ for k, v in pairs( self.AmmoLink ) do
+ if v == Target then
+ return false, "That crate is already linked to this gun!"
+ end
+ end
+
+ table.insert( self.AmmoLink, Target )
+ table.insert( Target.Master, self )
+
+ if self.BulletData.Type == "Empty" and Target.Load then
+ self:UnloadAmmo()
+ --self.Reloading = true
+ end
+
+ self.ReloadTime = ( ( math.max(Target.BulletData.RoundVolume,self.MinLengthBonus) / 500 ) ^ 0.60 ) * self.RoFmod * self.PGRoFmod
+ self.RateOfFire = 60 / self.ReloadTime
+ Wire_TriggerOutput( self, "Fire Rate", self.RateOfFire )
+ Wire_TriggerOutput( self, "Muzzle Weight", math.floor( Target.BulletData.ProjMass * 1000 ) )
+ Wire_TriggerOutput( self, "Muzzle Velocity", math.floor( Target.BulletData.MuzzleVel * ACF.VelScale ) )
+
+ return true, "Link successful!"
+
+end
+
+function ENT:Unlink( Target )
+
+ local Success = false
+ for Key,Value in pairs(self.AmmoLink) do
+ if Value == Target then
+ table.remove(self.AmmoLink,Key)
+ Success = true
+ end
+ end
+
+ if Success then
+ return true, "Unlink successful!"
+ else
+ return false, "That entity is not linked to this gun!"
+ end
+
+end
+
+function ENT:CanProperty( ply, property )
+
+ if property == "bodygroups" then
+ local longbarrel = list.Get("ACFClasses").GunClass[self.Class].longbarrel
+ if longbarrel ~= nil then
+ timer.Simple(0.25, function() --need to wait until after the property is actually set
+ if self:GetBodygroup( longbarrel.index ) == longbarrel.submodel then
+ local Muzzle = self:GetAttachment( self:LookupAttachment( longbarrel.newpos ) )
+ self.Muzzle = self:WorldToLocal(Muzzle.Pos)
+ else
+ local Muzzle = self:GetAttachment( self:LookupAttachment( "muzzle" ) )
+ self.Muzzle = self:WorldToLocal(Muzzle.Pos)
+ end
+ end)
+ end
+ end
+
+ return true
+
+end
+
+local WireTable = { "gmod_wire_adv_pod", "gmod_wire_pod", "gmod_wire_keyboard", "gmod_wire_joystick", "gmod_wire_joystick_multi" }
+
+function ENT:GetUser( inp )
+ if not inp then return nil end
+ if inp:GetClass() == "gmod_wire_adv_pod" then
+ if inp.Pod then
+ return inp.Pod:GetDriver()
+ end
+ elseif inp:GetClass() == "gmod_wire_pod" then
+ if inp.Pod then
+ return inp.Pod:GetDriver()
+ end
+ elseif inp:GetClass() == "gmod_wire_keyboard" then
+ if inp.ply then
+ return inp.ply
+ end
+ elseif inp:GetClass() == "gmod_wire_joystick" then
+ if inp.Pod then
+ return inp.Pod:GetDriver()
+ end
+ elseif inp:GetClass() == "gmod_wire_joystick_multi" then
+ if inp.Pod then
+ return inp.Pod:GetDriver()
+ end
+ elseif inp:GetClass() == "gmod_wire_expression2" then
+ if inp.Inputs.Fire then
+ return self:GetUser(inp.Inputs.Fire.Src)
+ elseif inp.Inputs.Shoot then
+ return self:GetUser(inp.Inputs.Shoot.Src)
+ elseif inp.Inputs then
+ for _,v in pairs(inp.Inputs) do
+ if v.Src then
+ if table.HasValue(WireTable, v.Src:GetClass()) then
+ return self:GetUser(v.Src)
+ end
+ end
+ end
+ end
+ end
+ return inp.Owner or inp:GetOwner()
+
+end
+
+function ENT:TriggerInput( iname, value )
+
+ if (iname == "Unload" and value > 0 and !self.Reloading) then
+ self:UnloadAmmo()
+ elseif ( iname == "Fire" and value > 0 and ACF.GunfireEnabled and self.Legal ) then
+ if self.NextFire < CurTime() then
+ self.User = self:GetUser(self.Inputs.Fire.Src) or self.Owner
+ if not IsValid(self.User) then self.User = self.Owner end
+ self:FireShell()
+ self:Think()
+ end
+ self.Firing = true
+ elseif ( iname == "Fire" and value <= 0 ) then
+ self.Firing = false
+ elseif ( iname == "Reload" and value ~= 0 ) then
+ self.Reloading = true
+ end
+end
+
+local function RetDist( enta, entb )
+ if not ((enta and enta:IsValid()) or (entb and entb:IsValid())) then return 0 end
+ disp = enta:GetPos() - entb:GetPos()
+ dist = math.sqrt( disp.x * disp.x + disp.y * disp.y + disp.z * disp.z )
+ return dist
+end
+
+function ENT:Think()
+
+ if ACF.CurTime > self.NextLegalCheck then
+
+ -- check gun is legal
+ self.Legal, self.LegalIssues = ACF_CheckLegal(self, self.Model, self.Mass, self.ModelInertia, false, true, false, true)
+ self.NextLegalCheck = ACF.LegalSettings:NextCheck(self.Legal)
+
+ -- check the seat is legal
+ local seat = IsValid(self.User) and self.User:GetVehicle() or nil
+ --if IsValid(self.User) then
+ -- local seat = self.User:GetVehicle()
+ if IsValid(seat) then
+ local legal, issues = ACF_CheckLegal(seat, nil, nil, nil, false, true, false, false)
+ if not legal then
+ self.Legal = false
+ self.LegalIssues = self.LegalIssues .. "\nSeat not legal: " .. issues
+ end
+ end
+ --end
+
+ self:UpdateOverlayText()
+
+ if not self.Legal then
+ if self.Firing then self:TriggerInput("Fire",0) end
+ end
+ end
+
+ local Time = CurTime()
+ if self.LastSend+1 <= Time then
+ local Ammo = 0
+ local CrateBonus = {}
+ local rofbonus = 0
+ local totalcap = 0
+
+ for Key, Crate in pairs(self.AmmoLink) do
+ if IsValid( Crate ) and Crate.Load and Crate.Legal then
+ if RetDist( self, Crate ) < 512 then
+ Ammo = Ammo + (Crate.Ammo or 0)
+ CrateBonus[Crate.RoFMul] = (CrateBonus[Crate.RoFMul] or 0) + Crate.Capacity
+ totalcap = totalcap + Crate.Capacity
+ else
+ self:Unlink( Crate )
+ soundstr = "physics/metal/metal_box_impact_bullet" .. tostring(math.random(1, 3)) .. ".wav"
+ self:EmitSound(soundstr,500,100)
+ end
+ end
+ end
+
+ for mul, cap in pairs(CrateBonus) do
+ rofbonus = rofbonus + (cap/totalcap)*mul
+ end
+
+ self.CrateBonus = rofbonus or 1
+ self.Ammo = Ammo
+ self:UpdateOverlayText()
+
+ Wire_TriggerOutput(self, "AmmoCount", Ammo)
+
+
+ if( self.MagSize ) then
+ Wire_TriggerOutput(self, "Shots Left", self.MagSize - self.CurrentShot)
+ else
+ Wire_TriggerOutput(self, "Shots Left", 1)
+ end
+
+ self:SetNWString("GunType",self.Id)
+ self:SetNWInt("Ammo",Ammo)
+ self:SetNWString("Type",self.BulletData.Type)
+ self:SetNWFloat("Mass",self.BulletData.ProjMass*100)
+ self:SetNWFloat("Propellant",self.BulletData.PropMass*1000)
+ self:SetNWFloat("FireRate",self.RateOfFire)
+
+ self.LastSend = Time
+
+ end
+
+ if self.NextFire <= Time then
+ self.Ready = true
+ Wire_TriggerOutput(self, "Ready", 1)
+
+ if self.MagSize and self.MagSize == 1 then
+ self.CurrentShot = 0
+ end
+
+ if self.Firing then
+ self:FireShell()
+ elseif self.Reloading then
+ self:ReloadMag()
+ self.Reloading = false
+ end
+ end
+
+ self:NextThink(Time)
+ return true
+
+end
+
+-- BNK ggg stuff, still used?
+function ENT:CheckWeight()
+ local mass = self:GetPhysicsObject():GetMass()
+ local maxmass = GetConVarNumber("bnk_maxweight") * 1000 + 999
+
+ local chk = false
+
+ local allents = constraint.GetAllConstrainedEntities( self )
+ for _, ent in pairs(allents) do
+ if (ent and ent:IsValid() and not ent:IsPlayer() and not (ent == self)) then
+ local phys = ent:GetPhysicsObject()
+ if(phys:IsValid()) then
+ mass = mass + phys:GetMass()
+ end
+ end
+ end
+
+ if( mass < maxmass ) then
+ chk = true
+ end
+
+ return chk
+end
+
+function ENT:ReloadMag()
+ if(self.IsUnderWeight == nil) then
+ self.IsUnderWeight = true
+ if(ISBNK) then
+ self.IsUnderWeight = self:CheckWeight()
+ end
+ end
+ if ( (self.CurrentShot > 0) and self.IsUnderWeight and self.Ready and self.Legal ) then
+ if ( ACF.RoundTypes[self.BulletData.Type] ) then --Check if the roundtype loaded actually exists
+ self:LoadAmmo(self.MagReload, false)
+ self:EmitSound("weapons/357/357_reload4.wav",500,100)
+ self.CurrentShot = 0
+ Wire_TriggerOutput(self, "Ready", 0)
+ else
+ self.CurrentShot = 0
+ self.Ready = false
+ Wire_TriggerOutput(self, "Ready", 0)
+ self:LoadAmmo(false, true)
+ end
+ end
+end
+
+function ENT:GetInaccuracy()
+ local SpreadScale = ACF.SpreadScale
+ local IaccMult = 1
+
+ if (self.ACF.Health and self.ACF.MaxHealth) then
+ IaccMult = math.Clamp(((1 - SpreadScale) / (0.5)) * ((self.ACF.Health/self.ACF.MaxHealth) - 1) + 1, 1, SpreadScale)
+ end
+
+ local coneAng = self.Inaccuracy * ACF.GunInaccuracyScale * IaccMult
+
+ return coneAng
+end
+
+
+
+function ENT:FireShell()
+
+ local CanDo = hook.Run("ACF_FireShell", self, self.BulletData )
+ if CanDo == false then return end
+ if(self.IsUnderWeight == nil) then
+ self.IsUnderWeight = true
+ if(ISBNK) then
+ self.IsUnderWeight = self:CheckWeight()
+ end
+ end
+
+ local bool = true
+ if(ISSITP) then
+ if(self.sitp_spacetype != "space" and self.sitp_spacetype != "planet") then
+ bool = false
+ end
+ if(self.sitp_core == false) then
+ bool = false
+ end
+ end
+
+ if ( bool and self.IsUnderWeight and self.Ready and self.Legal ) then
+ Blacklist = {}
+ if not ACF.AmmoBlacklist[self.BulletData.Type] then
+ Blacklist = {}
+ else
+ Blacklist = ACF.AmmoBlacklist[self.BulletData.Type]
+ end
+ if ( ACF.RoundTypes[self.BulletData.Type] and !table.HasValue( Blacklist, self.Class ) ) then --Check if the roundtype loaded actually exists
+
+ local MuzzlePos = self:LocalToWorld(self.Muzzle)
+ local MuzzleVec = self:GetForward()
+
+ local coneAng = math.tan(math.rad(self:GetInaccuracy()))
+ local randUnitSquare = (self:GetUp() * (2 * math.random() - 1) + self:GetRight() * (2 * math.random() - 1))
+ local spread = randUnitSquare:GetNormalized() * coneAng * (math.random() ^ (1 / math.Clamp(ACF.GunInaccuracyBias, 0.5, 4)))
+ local ShootVec = (MuzzleVec + spread):GetNormalized()
+
+ self:MuzzleEffect( MuzzlePos, MuzzleVec )
+
+ self.BulletData.Pos = MuzzlePos
+ self.BulletData.Flight = ShootVec * self.BulletData.MuzzleVel * 39.37 + ACF_GetPhysicalParent(self):GetVelocity()
+ self.BulletData.Owner = self.User
+ self.BulletData.Gun = self
+ self.CreateShell = ACF.RoundTypes[self.BulletData.Type].create
+ self:CreateShell( self.BulletData )
+
+ local HasPhys = constraint.FindConstraintEntity(self, "Weld"):IsValid() or not self:GetParent():IsValid()
+ ACF_KEShove(self, HasPhys and util.LocalToWorld(self, self:GetPhysicsObject():GetMassCenter(), 0) or self:GetPos(), -self:GetForward(), (self.BulletData.ProjMass * self.BulletData.MuzzleVel * 39.37 + self.BulletData.PropMass * 3000 * 39.37)*(GetConVarNumber("acf_recoilpush") or 1) )
+
+ self.Ready = false
+ self.CurrentShot = math.min(self.CurrentShot + 1, self.MagSize)
+ if((self.CurrentShot >= self.MagSize) and (self.MagSize > 1)) then
+ self:LoadAmmo(self.MagReload, false)
+ self:EmitSound("weapons/357/357_reload4.wav",500,100)
+ timer.Simple(self.LastLoadDuration, function() if IsValid(self) then self.CurrentShot = 0 end end)
+ else
+ self:LoadAmmo(false, false)
+ end
+ Wire_TriggerOutput(self, "Ready", 0)
+ else
+ self.CurrentShot = 0
+ self.Ready = false
+ Wire_TriggerOutput(self, "Ready", 0)
+ self:LoadAmmo(false, true)
+ end
+ end
+
+end
+
+function ENT:CreateShell()
+ --You overwrite this with your own function, defined in the ammo definition file
+end
+
+function ENT:FindNextCrate()
+
+ local MaxAmmo = table.getn(self.AmmoLink)
+ local AmmoEnt = nil
+ local i = 0
+
+ while i <= MaxAmmo and not (AmmoEnt and AmmoEnt:IsValid() and AmmoEnt.Ammo > 0) do -- need to check ammoent here? returns if found
+
+ self.CurAmmo = self.CurAmmo + 1
+ if self.CurAmmo > MaxAmmo then self.CurAmmo = 1 end
+
+ AmmoEnt = self.AmmoLink[self.CurAmmo]
+ if AmmoEnt and AmmoEnt:IsValid() and AmmoEnt.Ammo > 0 and AmmoEnt.Load and AmmoEnt.Legal then
+ return AmmoEnt
+ end
+ AmmoEnt = nil
+
+ i = i + 1
+ end
+
+ return false
+end
+
+function ENT:LoadAmmo( AddTime, Reload )
+
+ local AmmoEnt = self:FindNextCrate()
+ local curTime = CurTime()
+
+ if AmmoEnt and AmmoEnt.Legal then
+ AmmoEnt.Ammo = AmmoEnt.Ammo - 1
+ self.BulletData = AmmoEnt.BulletData
+ self.BulletData.Crate = AmmoEnt:EntIndex()
+
+ local cb = 1
+ if(self.CrateBonus and (self.MagReload == 0)) then
+ cb = self.CrateBonus
+ if (cb == 0) then cb = 1 end
+ end
+
+ local Adj = not self.BulletData.LengthAdj and 1 or self.BulletData.LengthAdj --FL firerate bonus adjustment
+
+ self.ReloadTime = ( ( math.max(self.BulletData.RoundVolume,self.MinLengthBonus*Adj) / 500 ) ^ 0.60 ) * self.RoFmod * self.PGRoFmod * cb
+ Wire_TriggerOutput(self, "Loaded", self.BulletData.Type)
+
+ self.RateOfFire = (60/self.ReloadTime)
+ Wire_TriggerOutput(self, "Fire Rate", self.RateOfFire)
+ Wire_TriggerOutput(self, "Muzzle Weight", math.floor(self.BulletData.ProjMass*1000) )
+ Wire_TriggerOutput(self, "Muzzle Velocity", math.floor(self.BulletData.MuzzleVel*ACF.VelScale) )
+
+ self.NextFire = curTime + self.ReloadTime
+ local reloadTime = self.ReloadTime
+
+ if AddTime then
+ reloadTime = reloadTime + AddTime * self.CrateBonus
+ end
+ if Reload then
+ self:ReloadEffect()
+ end
+
+ if self.FirstLoad then
+ self.FirstLoad = false
+ reloadTime = 0.1
+ end
+
+ self.NextFire = curTime + reloadTime
+ self.LastLoadDuration = reloadTime
+
+ self:Think()
+ return true
+ else
+ self.BulletData = {}
+ self.BulletData.Type = "Empty"
+ self.BulletData.PropMass = 0
+ self.BulletData.ProjMass = 0
+
+ self:EmitSound("weapons/pistol/pistol_empty.wav",500,100)
+ Wire_TriggerOutput(self, "Loaded", "Empty")
+
+ self.NextFire = curTime + 0.5
+ self:Think()
+ end
+ return false
+
+end
+
+function ENT:UnloadAmmo()
+
+ if not self.BulletData or not self.BulletData.Crate then return end -- Explanation: http://www.youtube.com/watch?v=dwjrui9oCVQ
+ if not self.Ready then
+ if (self.NextFire-CurTime()) < 0 then return end -- see above; preventing spam
+ if self.MagSize > 1 and self.CurrentShot >= self.MagSize then return end -- prevent unload in middle of mag reload
+ end
+
+ local Crate = Entity( self.BulletData.Crate )
+ if Crate and Crate:IsValid() and self.BulletData.Type == Crate.BulletData.Type then
+ Crate.Ammo = math.min(Crate.Ammo+1, Crate.Capacity)
+ end
+
+ self.Ready = false
+ Wire_TriggerOutput(self, "Ready", 0)
+ self:EmitSound("weapons/357/357_reload4.wav",500,100)
+
+ local unloadtime = self.ReloadTime/2 -- base time to swap a fully loaded shell out
+ if self.NextFire < CurTime() then -- unloading in middle of reload
+ unloadtime = math.min(unloadtime, math.max(self.ReloadTime - (self.NextFire - CurTime()),0) )
+ end
+ self:LoadAmmo( unloadtime, true )
+
+end
+
+function ENT:MuzzleEffect()
+
+ local Effect = EffectData()
+ Effect:SetEntity( self )
+ Effect:SetScale( self.BulletData.PropMass )
+ Effect:SetMagnitude( self.ReloadTime )
+ Effect:SetSurfaceProp( ACF.RoundTypes[self.BulletData.Type].netid ) --Encoding the ammo type into a table index
+ util.Effect( "ACF_MuzzleFlash", Effect, true, true )
+
+end
+
+function ENT:ReloadEffect()
+
+ local Effect = EffectData()
+ Effect:SetEntity( self )
+ Effect:SetScale( 0 )
+ Effect:SetMagnitude( self.ReloadTime )
+ Effect:SetSurfaceProp( ACF.RoundTypes[self.BulletData.Type].netid ) --Encoding the ammo type into a table index
+ util.Effect( "ACF_MuzzleFlash", Effect, true, true )
+
+end
+
+function ENT:PreEntityCopy()
+
+ local info = {}
+ local entids = {}
+ for Key, Value in pairs(self.AmmoLink) do --First clean the table of any invalid entities
+ if not Value:IsValid() then
+ table.remove(self.AmmoLink, Value)
+ end
+ end
+ for Key, Value in pairs(self.AmmoLink) do --Then save it
+ table.insert(entids, Value:EntIndex())
+ end
+ info.entities = entids
+ if info.entities then
+ duplicator.StoreEntityModifier( self, "ACFAmmoLink", info )
+ end
+
+ --Wire dupe info
+ self.BaseClass.PreEntityCopy( self )
+
+end
+
+function ENT:PostEntityPaste( Player, Ent, CreatedEntities )
+
+ if (Ent.EntityMods) and (Ent.EntityMods.ACFAmmoLink) and (Ent.EntityMods.ACFAmmoLink.entities) then
+ local AmmoLink = Ent.EntityMods.ACFAmmoLink
+ if AmmoLink.entities and table.Count(AmmoLink.entities) > 0 then
+ for _,AmmoID in pairs(AmmoLink.entities) do
+ local Ammo = CreatedEntities[ AmmoID ]
+ if Ammo and Ammo:IsValid() and Ammo:GetClass() == "acf_ammo" then
+ self:Link( Ammo )
+ end
+ end
+ end
+ Ent.EntityMods.ACFAmmoLink = nil
+ end
+
+ --Wire dupe info
+ self.BaseClass.PostEntityPaste( self, Player, Ent, CreatedEntities )
+
+end
diff --git a/lua/entities/debris.lua b/lua/entities/debris.lua
new file mode 100644
index 000000000..73607b91d
--- /dev/null
+++ b/lua/entities/debris.lua
@@ -0,0 +1,45 @@
+
+AddCSLuaFile()
+
+DEFINE_BASECLASS( "base_anim" )
+
+ENT.PrintName = "Debris"
+
+if CLIENT then return end
+
+-- todo: rename this to acf_debris
+
+function ENT:Initialize()
+
+ self.Timer = CurTime() + 60
+ self:PhysicsInit( SOLID_VPHYSICS )
+ self:SetMoveType( MOVETYPE_VPHYSICS )
+ self:SetSolid( SOLID_VPHYSICS )
+ self:SetCollisionGroup( COLLISION_GROUP_WORLD )
+
+ local phys = self:GetPhysicsObject()
+ if IsValid( phys ) then
+ phys:Wake()
+ end
+
+end
+
+function ENT:Think()
+
+ if self.Timer < CurTime() then
+ self:Remove()
+ end
+
+ self:NextThink( CurTime() + 60 )
+
+ return true
+
+end
+
+function ENT:OnTakeDamage( dmginfo )
+
+ -- React physically when shot/getting blown
+ -- not sure if this is actually necessary
+ self:TakePhysicsDamage( dmginfo )
+
+end
diff --git a/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua b/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua
new file mode 100644
index 000000000..69cbdf0e2
--- /dev/null
+++ b/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua
@@ -0,0 +1,1037 @@
+E2Lib.RegisterExtension("acf", true)
+-- [ To Do ] --
+-- #prop armor
+--get incident armor ?
+--hit calcs ?
+--conversions ?
+
+
+--DON'T FORGET TO UPDATE cl_acfdescriptions.lua WHEN ADDING FUNCTIONS
+
+
+-- [ Helper Functions ] --
+
+local function isEngine(ent)
+ if not validPhysics(ent) then return false end
+ if (ent:GetClass() == "acf_engine") then return true else return false end
+end
+
+local function isGearbox(ent)
+ if not validPhysics(ent) then return false end
+ if (ent:GetClass() == "acf_gearbox") then return true else return false end
+end
+
+local function isGun(ent)
+ if not validPhysics(ent) then return false end
+ if (ent:GetClass() == "acf_gun") then return true else return false end
+end
+
+local function isAmmo(ent)
+ if not validPhysics(ent) then return false end
+ if (ent:GetClass() == "acf_ammo") then return true else return false end
+end
+
+local function isFuel(ent)
+ if not validPhysics(ent) then return false end
+ if (ent:GetClass() == "acf_fueltank") then return true else return false end
+end
+
+local function reloadTime(ent)
+ if ent.CurrentShot and ent.CurrentShot > 0 then return ent.ReloadTime end
+ return ent.MagReload
+end
+
+local function restrictInfo(ply, ent)
+ if GetConVar("sbox_acf_restrictinfo"):GetInt() != 0 then
+ if isOwner(ply, ent) then return false else return true end
+ end
+ return false
+end
+
+local function getMaxTorque(ent)
+ if not isEngine(ent) then return 0 end
+ return ent.PeakTorque or 0
+end
+
+local function getMaxPower(ent)
+ if not isEngine(ent) then return 0 end
+ local peakpower
+ if ent.iselec then
+ peakpower = math.floor(ent.PeakTorque * ent.LimitRPM / (38195.2)) --(4*9548.8)
+ else
+ peakpower = math.floor(ent.PeakTorque * ent.PeakMaxRPM / 9548.8)
+ end
+ return peakpower or 0
+end
+
+local function isLinkableACFEnt(ent)
+
+ if not validPhysics(ent) then return false end
+
+ local entClass = ent:GetClass()
+
+ return ACF_E2_LinkTables[entClass] ~= nil
+
+end
+
+
+-- [General Functions ] --
+
+
+__e2setcost( 1 )
+
+-- Returns 1 if functions returning sensitive info are restricted to owned props
+e2function number acfInfoRestricted()
+ return GetConVar("sbox_acf_restrictinfo"):GetInt() or 0
+end
+
+-- Returns the short name of an ACF entity
+e2function string entity:acfNameShort()
+ if isEngine(this) then return this.Id or "" end
+ if isGearbox(this) then return this.Id or "" end
+ if isGun(this) then return this.Id or "" end
+ if isAmmo(this) then return this.RoundId or "" end
+ if isFuel(this) then return this.FuelType .." ".. this.SizeId end
+ return ""
+end
+
+-- Returns the capacity of an acf ammo crate or fuel tank
+e2function number entity:acfCapacity()
+ if not (isAmmo(this) or isFuel(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return this.Capacity or 0
+end
+
+-- Returns 1 if an ACF engine, ammo crate, or fuel tank is on
+e2function number entity:acfActive()
+ if not (isEngine(this) or isAmmo(this) or isFuel(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not isAmmo(this) then
+ if (this.Active) then return 1 end
+ else
+ if (this.Load) then return 1 end
+ end
+ return 0
+end
+
+-- Turns an ACF engine, ammo crate, or fuel tank on or off
+e2function void entity:acfActive( number on )
+ if not (isEngine(this) or isAmmo(this) or isFuel(this)) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Active", on)
+end
+
+__e2setcost( 5 )
+
+--returns 1 if hitpos is on a clipped part of prop
+e2function number entity:acfHitClip( vector hitpos )
+ if not isOwner(self, this) then return 0 end
+ if ACF_CheckClips(this, hitpos) then return 1 else return 0 end
+end
+
+__e2setcost( 1 )
+
+
+
+ACF_E2_LinkTables = ACF_E2_LinkTables or
+{ -- link resources within each ent type. should point to an ent: true if adding link.Ent, false to add link itself
+ acf_engine = {GearLink = true, FuelLink = false},
+ acf_gearbox = {WheelLink = true, Master = false},
+ acf_fueltank = {Master = false},
+ acf_gun = {AmmoLink = false},
+ acf_ammo = {Master = false}
+}
+
+
+local function getLinks(ent, enttype)
+
+ local ret = {}
+ -- find the link resources available for this ent type
+ for entry, mode in pairs(ACF_E2_LinkTables[enttype]) do
+ if not ent[entry] then error("Couldn't find link resource " .. entry .. " for entity " .. tostring(ent)) return end
+
+ -- find all the links inside the resources
+ for _, link in pairs(ent[entry]) do
+ ret[#ret+1] = mode and link.Ent or link
+ end
+ end
+
+ return ret
+end
+
+
+local function searchForGearboxLinks(ent)
+ local boxes = ents.FindByClass("acf_gearbox")
+
+ local ret = {}
+
+ for _, box in pairs(boxes) do
+ if IsValid(box) then
+ for _, link in pairs(box.WheelLink) do
+ if link.Ent == ent then
+ ret[#ret+1] = box
+ break
+ end
+ end
+ end
+ end
+
+ return ret
+end
+
+
+__e2setcost( 20 )
+
+e2function array entity:acfLinks()
+
+ if not IsValid(this) then return {} end
+
+ local enttype = this:GetClass()
+
+ if not ACF_E2_LinkTables[enttype] then
+ return searchForGearboxLinks(this)
+ end
+
+ return getLinks(this, enttype)
+
+end
+
+
+
+
+__e2setcost( 2 )
+
+-- Returns the full name of an ACF entity
+e2function string entity:acfName()
+ if isAmmo(this) then return (this.RoundId .. " " .. this.RoundType) end
+ if isFuel(this) then return this.FuelType .." ".. this.SizeId end
+ local acftype = ""
+ if isEngine(this) then acftype = "Mobility" end
+ if isGearbox(this) then acftype = "Mobility" end
+ if isGun(this) then acftype = "Guns" end
+ if (acftype == "") then return "" end
+ local List = list.Get("ACFEnts")
+ return List[acftype][this.Id]["name"] or ""
+end
+
+-- Returns the type of ACF entity
+e2function string entity:acfType()
+ if isEngine(this) or isGearbox(this) then
+ local List = list.Get("ACFEnts")
+ return List["Mobility"][this.Id]["category"] or ""
+ end
+ if isGun(this) then
+ local Classes = list.Get("ACFClasses")
+ return Classes["GunClass"][this.Class]["name"] or ""
+ end
+ if isAmmo(this) then return this.RoundType or "" end
+ if isFuel(this) then return this.FuelType or "" end
+ return ""
+end
+
+--allows e2 to perform ACF links
+e2function number entity:acfLinkTo(entity target, number notify)
+ if not (isLinkableACFEnt(this)) and (isOwner(self, this) and isOwner(self, target)) then
+ if notify > 0 then
+ ACF_SendNotify(self.player, 0, "Must be called on a gun, engine, or gearbox you own.")
+ end
+ return 0
+ end
+
+ local success, msg = this:Link(target)
+ if notify > 0 then
+ ACF_SendNotify(self.player, success, msg)
+ end
+ return success and 1 or 0
+end
+
+--allows e2 to perform ACF unlinks
+e2function number entity:acfUnlinkFrom(entity target, number notify)
+ if not (isLinkableACFEnt(this)) and (isOwner(self, this) and isOwner(self, target)) then
+ if notify > 0 then
+ ACF_SendNotify(self.player, 0, "Must be called on a gun, engine, or gearbox you own.")
+ end
+ return 0
+ end
+
+ local success, msg = this:Unlink(target)
+ if notify > 0 then
+ ACF_SendNotify(self.player, success, msg)
+ end
+ return success and 1 or 0
+end
+
+-- returns any wheels linked to this engine/gearbox or child gearboxes
+e2function array entity:acfGetLinkedWheels()
+ if not (isEngine(this) or isGearbox(this)) then return {} end
+ local wheels = {}
+ for k,ent in pairs( ACF_GetLinkedWheels( this ) ) do -- we need to switch from grody indexing by ent, to numerical indexing
+ table.insert(wheels, ent)
+ end
+ return wheels
+end
+
+--returns current acf dragdivisor
+e2function number acfDragDiv()
+ return ACF.DragDiv
+end
+
+-- [ Engine Functions ] --
+
+
+__e2setcost( 1 )
+
+-- Returns 1 if the entity is an ACF engine
+e2function number entity:acfIsEngine()
+ if isEngine(this) then return 1 else return 0 end
+end
+
+-- Returns 1 if an ACF engine is electric
+e2function number entity:acfIsElectric()
+ if ( this.iselec == true ) then return 1 else return 0 end
+end
+
+-- Returns the torque in N/m of an ACF engine
+e2function number entity:acfMaxTorque()
+ return getMaxTorque(this)
+end
+
+-- Returns the power in kW of an ACF engine
+e2function number entity:acfMaxPower()
+ return getMaxPower(this)
+end
+
+-- Same as the two above just with fuel duhhh//
+
+e2function number entity:acfMaxTorqueWithFuel()
+ return getMaxTorque(this)*ACF.TorqueBoost or 0
+end
+
+-- Detailed explanation of this function
+
+e2function number entity:acfMaxPowerWithFuel()
+ return getMaxPower(this)*ACF.TorqueBoost or 0
+end
+
+--//
+
+-- Returns the idle rpm of an ACF engine
+e2function number entity:acfIdleRPM()
+ if not isEngine(this) then return 0 end
+ return this.IdleRPM or 0
+end
+
+-- Returns the powerband min of an ACF engine
+e2function number entity:acfPowerbandMin()
+ if not isEngine(this) then return 0 end
+ if ( this.iselec == true ) then
+ return math.max(this.IdleRPM, this.PeakMinRPM)
+ else
+ return this.PeakMinRPM or 0
+ end
+end
+
+-- Returns the powerband max of an ACF engine
+e2function number entity:acfPowerbandMax()
+ if not isEngine(this) then return 0 end
+ if ( this.iselec == true ) then
+ return math.floor(this.LimitRPM / 2)
+ else
+ return this.PeakMaxRPM or 0
+ end
+end
+
+-- Returns the redline rpm of an ACF engine
+e2function number entity:acfRedline()
+ if not isEngine(this) then return 0 end
+ return this.LimitRPM or 0
+end
+
+-- Returns the current rpm of an ACF engine
+e2function number entity:acfRPM()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return math.floor(this.FlyRPM or 0)
+end
+
+-- Returns the current torque of an ACF engine
+e2function number entity:acfTorque()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return math.floor(this.Torque or 0)
+end
+
+-- Returns the inertia of an ACF engine's flywheel
+e2function number entity:acfFlyInertia()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this ) then return 0 end
+ return this.Inertia or 0
+end
+
+-- Returns the mass of an ACF engine's flywheel
+e2function number entity:acfFlyMass()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this ) then return 0 end
+ return this.Inertia / (3.1416)^2 or 0
+end
+
+-- Returns the current power of an ACF engine
+e2function number entity:acfPower()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return math.floor((this.Torque or 0) * (this.FlyRPM or 0) / 9548.8)
+end
+
+-- Returns 1 if the RPM of an ACF engine is inside the powerband
+e2function number entity:acfInPowerband()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+
+ local pbmin
+ local pbmax
+
+ if (this.iselec == true )then
+ pbmin = this.IdleRPM
+ pbmax = math.floor(this.LimitRPM / 2)
+ else
+ pbmin = this.PeakMinRPM
+ pbmax = this.PeakMaxRPM
+ end
+
+ if (this.FlyRPM < pbmin) then return 0 end
+ if (this.FlyRPM > pbmax) then return 0 end
+
+ return 1
+end
+
+-- Returns the throttle of an ACF engine
+e2function number entity:acfThrottle()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return (this.Throttle or 0) * 100
+end
+
+__e2setcost( 5 )
+
+-- Sets the throttle value for an ACF engine
+e2function void entity:acfThrottle( number throttle )
+ if not isEngine(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Throttle", throttle)
+end
+
+
+-- [ Gearbox Functions ] --
+
+
+__e2setcost( 1 )
+
+-- Returns 1 if the entity is an ACF gearbox
+e2function number entity:acfIsGearbox()
+ if isGearbox(this) then return 1 else return 0 end
+end
+
+-- Returns the current gear for an ACF gearbox
+e2function number entity:acfGear()
+ if not isGearbox(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return this.Gear or 0
+end
+
+-- Returns the number of gears for an ACF gearbox
+e2function number entity:acfNumGears()
+ if not isGearbox(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return this.Gears or 0
+end
+
+-- Returns the final ratio for an ACF gearbox
+e2function number entity:acfFinalRatio()
+ if not isGearbox(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return this.GearTable["Final"] or 0
+end
+
+-- Returns the total ratio (current gear * final) for an ACF gearbox
+e2function number entity:acfTotalRatio()
+ if not isGearbox(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return this.GearRatio or 0
+end
+
+-- Returns the max torque for an ACF gearbox
+e2function number entity:acfTorqueRating()
+ if not isGearbox(this) then return 0 end
+ return this.MaxTorque or 0
+end
+
+-- Returns whether an ACF gearbox is dual clutch
+e2function number entity:acfIsDual()
+ if not isGearbox(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if (this.Dual) then return 1 end
+ return 0
+end
+
+-- Returns the time in ms an ACF gearbox takes to change gears
+e2function number entity:acfShiftTime()
+ if not isGearbox(this) then return 0 end
+ return (this.SwitchTime or 0) * 1000
+end
+
+-- Returns 1 if an ACF gearbox is in gear
+e2function number entity:acfInGear()
+ if not isGearbox(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if (this.InGear) then return 1 end
+ return 0
+end
+
+-- Returns the ratio for a specified gear of an ACF gearbox
+e2function number entity:acfGearRatio( number gear )
+ if not isGearbox(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ local g = math.Clamp(math.floor(gear),1,this.Gears)
+ return this.GearTable[g] or 0
+end
+
+-- Returns the current torque output for an ACF gearbox
+e2function number entity:acfTorqueOut()
+ if not isGearbox(this) then return 0 end
+ return math.min(this.TotalReqTq or 0, this.MaxTorque or 0) / (this.GearRatio or 1)
+end
+
+-- Sets the gear ratio of a CVT, set to 0 to use built-in algorithm
+e2function void entity:acfCVTRatio( number ratio )
+ if not isGearbox(this) then return end
+ if restrictInfo(self, this) then return end
+ if not this.CVT then return end
+ this.CVTRatio = math.Clamp(ratio,0,1)
+end
+
+__e2setcost( 5 )
+
+-- Sets the current gear for an ACF gearbox
+e2function void entity:acfShift( number gear )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Gear", gear)
+end
+
+-- Cause an ACF gearbox to shift up
+e2function void entity:acfShiftUp()
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Gear Up", 1) --doesn't need to be toggled off
+end
+
+-- Cause an ACF gearbox to shift down
+e2function void entity:acfShiftDown()
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Gear Down", 1) --doesn't need to be toggled off
+end
+
+-- Sets the brakes for an ACF gearbox
+e2function void entity:acfBrake( number brake )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Brake", brake)
+end
+
+-- Sets the left brakes for an ACF gearbox
+e2function void entity:acfBrakeLeft( number brake )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ if (not this.Dual) then return end
+ this:TriggerInput("Left Brake", brake)
+end
+
+-- Sets the right brakes for an ACF gearbox
+e2function void entity:acfBrakeRight( number brake )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ if (not this.Dual) then return end
+ this:TriggerInput("Right Brake", brake)
+end
+
+-- Sets the clutch for an ACF gearbox
+e2function void entity:acfClutch( number clutch )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Clutch", clutch)
+end
+
+-- Sets the left clutch for an ACF gearbox
+e2function void entity:acfClutchLeft( number clutch )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ if (not this.Dual) then return end
+ this:TriggerInput("Left Clutch", clutch)
+end
+
+-- Sets the right clutch for an ACF gearbox
+e2function void entity:acfClutchRight( number clutch )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ if (not this.Dual) then return end
+ this:TriggerInput("Right Clutch", clutch)
+end
+
+-- Sets the steer ratio for an ACF double differential gearbox
+e2function void entity:acfSteerRate( number rate )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ if (not this.DoubleDiff) then return end
+ this:TriggerInput("Steer Rate", rate)
+end
+
+-- Applies gear hold for an automatic ACF gearbox
+e2function void entity:acfHoldGear( number hold )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ if (not this.Auto) then return end
+ this:TriggerInput("Hold Gear", hold)
+end
+
+-- Sets the shift point scaling for an automatic ACF gearbox
+e2function void entity:acfShiftPointScale( number scale )
+ if not isGearbox(this) then return end
+ if not isOwner(self, this) then return end
+ if (not this.Auto) then return end
+ this:TriggerInput("Shift Speed Scale", scale)
+end
+
+
+-- [ Gun Functions ] --
+
+
+__e2setcost( 1 )
+
+-- Returns 1 if the entity is an ACF gun
+e2function number entity:acfIsGun()
+ if isGun(this) and not restrictInfo(self, this) then return 1 else return 0 end
+end
+
+-- Returns 1 if the ACF gun is ready to fire
+e2function number entity:acfReady()
+ if not isGun(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if (this.Ready) then return 1 end
+ return 0
+end
+
+-- Returns time to next shot of an ACF weapon
+__e2setcost( 3 )
+e2function number entity:acfReloadTime()
+ if restrictInfo(self, this) or not isGun(this) or this.Ready then return 0 end
+ return reloadTime(this)
+end
+
+-- Returns number between 0 and 1 which represents reloading progress of an ACF weapon. Useful for progress bars
+__e2setcost( 5 )
+e2function number entity:acfReloadProgress()
+ if restrictInfo(self, this) or not isGun(this) or this.Ready then return 1 end
+ return math.Clamp( 1 - (this.NextFire - CurTime()) / reloadTime(this), 0, 1 )
+end
+
+__e2setcost( 1 )
+
+-- returns time it takes for an ACF weapon to reload magazine
+e2function number entity:acfMagReloadTime()
+ if restrictInfo(self, this) or not isGun(this) or not this.MagReload then return 0 end
+ return this.MagReload
+end
+
+-- Returns the magazine size for an ACF gun
+e2function number entity:acfMagSize()
+ if not isGun(this) then return 0 end
+ return this.MagSize or 1
+end
+
+-- Returns the spread for an ACF gun or flechette ammo
+e2function number entity:acfSpread()
+ if not (isGun(this) or isAmmo(this)) then return 0 end
+ local Spread = this.GetInaccuracy and this:GetInaccuracy() or this.Inaccuracy or 0
+ if this.BulletData["Type"] == "FL" then
+ if restrictInfo(self, this) then return Spread end
+ return Spread + (this.BulletData["FlechetteSpread"] or 0)
+ end
+ return Spread
+end
+
+-- Returns 1 if an ACF gun is reloading
+e2function number entity:acfIsReloading()
+ if not isGun(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ --if (this.Reloading) then return 1 end
+ if not this.Ready then
+ if this.MagSize == 1 then
+ return 1
+ else
+ return this.CurrentShot >= this.MagSize and 1 or 0
+ end
+ end
+ return 0
+end
+
+-- Returns the rate of fire of an acf gun
+e2function number entity:acfFireRate()
+ if not isGun(this) then return 0 end
+ return math.Round(this.RateOfFire or 0,3)
+end
+
+-- Returns the number of rounds left in a magazine for an ACF gun
+e2function number entity:acfMagRounds()
+ if not isGun(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if (this.MagSize > 1) then
+ return (this.MagSize - this.CurrentShot) or 1
+ end
+ if (this.Ready) then return 1 end
+ return 0
+end
+
+-- Sets the firing state of an ACF weapon
+e2function void entity:acfFire( number fire )
+ if not isGun(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Fire", fire)
+end
+
+-- Causes an ACF weapon to unload
+e2function void entity:acfUnload()
+ if not isGun(this) then return end
+ if not isOwner(self, this) then return end
+ this:UnloadAmmo()
+end
+
+-- Causes an ACF weapon to reload
+e2function void entity:acfReload()
+ if not isGun(this) then return end
+ if not isOwner(self, this) then return end
+ this.Reloading = true
+end
+
+__e2setcost( 20 )
+
+--Returns the number of rounds in active ammo crates linked to an ACF weapon
+e2function number entity:acfAmmoCount()
+ if not isGun(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ local Ammo = 0
+ for Key,AmmoEnt in pairs(this.AmmoLink) do
+ if AmmoEnt and AmmoEnt:IsValid() and AmmoEnt["Load"] then
+ Ammo = Ammo + (AmmoEnt.Ammo or 0)
+ end
+ end
+ return Ammo
+end
+
+--Returns the number of rounds in all ammo crates linked to an ACF weapon
+e2function number entity:acfTotalAmmoCount()
+ if not isGun(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ local Ammo = 0
+ for Key,AmmoEnt in pairs(this.AmmoLink) do
+ if AmmoEnt and AmmoEnt:IsValid() then
+ Ammo = Ammo + (AmmoEnt.Ammo or 0)
+ end
+ end
+ return Ammo
+end
+
+-- [ Ammo Functions ] --
+
+
+__e2setcost( 1 )
+
+-- Returns 1 if the entity is an ACF ammo crate
+e2function number entity:acfIsAmmo()
+ if isAmmo(this) and not restrictInfo(self, this) then return 1 else return 0 end
+end
+
+-- Returns the rounds left in an acf ammo crate
+e2function number entity:acfRounds()
+ if not isAmmo(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return this.Ammo or 0
+end
+
+-- Returns the type of weapon the ammo in an ACF ammo crate loads into
+e2function string entity:acfRoundType() --cartridge?
+ if not isAmmo(this) then return "" end
+ if restrictInfo(self, this) then return "" end
+ return this.RoundType or ""
+end
+
+-- Returns the type of ammo in a crate or gun
+e2function string entity:acfAmmoType()
+ if not (isAmmo(this) or isGun(this)) then return "" end
+ if restrictInfo(self, this) then return "" end
+ return this.BulletData["Type"] or ""
+end
+
+-- Returns the caliber of an ammo or gun
+e2function number entity:acfCaliber()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return (this.Caliber or 0) * 10
+end
+
+-- Returns the muzzle velocity of the ammo in a crate or gun
+e2function number entity:acfMuzzleVel()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return math.Round((this.BulletData["MuzzleVel"] or 0)*ACF.VelScale,3)
+end
+
+-- Returns the mass of the projectile in a crate or gun
+e2function number entity:acfProjectileMass()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return math.Round(this.BulletData["ProjMass"] or 0,3)
+end
+
+-- Returns the number of projectiles in a flechette round
+e2function number entity:acfFLSpikes()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not this.BulletData["Type"] == "FL" then return 0 end
+ return this.BulletData["Flechettes"] or 0
+end
+
+-- Returns the mass of a single spike in a FL round in a crate or gun
+e2function number entity:acfFLSpikeMass()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not this.BulletData["Type"] == "FL" then return 0 end
+ return math.Round(this.BulletData["FlechetteMass"] or 0, 3)
+end
+
+-- Returns the radius of the spikes in a flechette round in mm
+e2function number entity:acfFLSpikeRadius()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not this.BulletData["Type"] == "FL" then return 0 end
+ return math.Round((this.BulletData["FlechetteRadius"] or 0) * 10, 3)
+end
+
+__e2setcost( 5 )
+
+-- Returns the penetration of an AP, APHE, or HEAT round
+e2function number entity:acfPenetration()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ local Type = this.BulletData["Type"] or ""
+ local Energy
+ if Type == "AP" or Type == "APHE" then
+ Energy = ACF_Kinetic(this.BulletData["MuzzleVel"]*39.37, this.BulletData["ProjMass"] - (this.BulletData["FillerMass"] or 0), this.BulletData["LimitVel"] )
+ return math.Round((Energy.Penetration/this.BulletData["PenAera"])*ACF.KEtoRHA,3)
+ elseif Type == "HEAT" then
+ local Crushed, HEATFillerMass, BoomFillerMass = ACF.RoundTypes["HEAT"].CrushCalc(this.BulletData.MuzzleVel, this.BulletData.FillerMass)
+ if Crushed == 1 then return 0 end -- no HEAT jet to fire off, it was all converted to HE
+ Energy = ACF_Kinetic(ACF.RoundTypes["HEAT"].CalcSlugMV( this.BulletData, HEATFillerMass )*39.37, this.BulletData["SlugMass"], 9999999 )
+ return math.Round((Energy.Penetration/this.BulletData["SlugPenAera"])*ACF.KEtoRHA,3)
+ elseif Type == "FL" then
+ Energy = ACF_Kinetic(this.BulletData["MuzzleVel"]*39.37 , this.BulletData["FlechetteMass"], this.BulletData["LimitVel"] )
+ return math.Round((Energy.Penetration/this.BulletData["FlechettePenArea"])*ACF.KEtoRHA, 3)
+ end
+ return 0
+end
+
+-- Returns the blast radius of an HE, APHE, or HEAT round
+e2function number entity:acfBlastRadius()
+ if not (isAmmo(this) or isGun(this)) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ local Type = this.BulletData["Type"] or ""
+ if Type == "HE" or Type == "APHE" then
+ return math.Round(this.BulletData["FillerMass"]^0.33*8,3)
+ elseif Type == "HEAT" then
+ return math.Round((this.BulletData["FillerMass"]/3)^0.33*8,3)
+ end
+ return 0
+end
+
+
+-- [ Armor Functions ] --
+
+
+__e2setcost( 1 )
+
+-- Returns the effective armor given an armor value and hit angle
+e2function number acfEffectiveArmor(number Armor, number Angle)
+ return math.Round(Armor/math.abs(math.cos(math.rad(math.min(Angle,89.999)))),1)
+end
+
+__e2setcost( 5 )
+
+-- Returns the current health of an entity
+e2function number entity:acfPropHealth()
+ if not validPhysics(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not ACF_Check(this) then return 0 end
+ return math.Round(this.ACF.Health or 0,3)
+end
+
+-- Returns the current armor of an entity
+e2function number entity:acfPropArmor()
+ if not validPhysics(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not ACF_Check(this) then return 0 end
+ return math.Round(this.ACF.Armour or 0,3)
+end
+
+-- Returns the max health of an entity
+e2function number entity:acfPropHealthMax()
+ if not validPhysics(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not ACF_Check(this) then return 0 end
+ return math.Round(this.ACF.MaxHealth or 0,3)
+end
+
+-- Returns the max armor of an entity
+e2function number entity:acfPropArmorMax()
+ if not validPhysics(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not ACF_Check(this) then return 0 end
+ return math.Round(this.ACF.MaxArmour or 0,3)
+end
+
+-- Returns the ductility of an entity
+e2function number entity:acfPropDuctility()
+ if not validPhysics(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not ACF_Check(this) then return 0 end
+ return (this.ACF.Ductility or 0)*100
+end
+
+-- Returns the effective armor from a trace hitting a prop
+e2function number ranger:acfEffectiveArmor()
+ if not (this and validPhysics(this.Entity)) then return 0 end
+ if restrictInfo(self, this.Entity) then return 0 end
+ if not ACF_Check(this.Entity) then return 0 end
+ return math.Round(this.Entity.ACF.Armour/math.abs( math.cos(math.rad(ACF_GetHitAngle( this.HitNormal , this.HitPos-this.StartPos )))),1)
+end
+
+
+-- [ Fuel Functions ] --
+
+
+__e2setcost( 1 )
+
+-- Returns 1 if the entity is an ACF fuel tank
+e2function number entity:acfIsFuel()
+ if isFuel(this) and not restrictInfo(self, this) then return 1 else return 0 end
+end
+
+-- Returns 1 if the current engine requires fuel to run
+e2function number entity:acfFuelRequired()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ return (this.RequiresFuel and 1) or 0
+end
+
+__e2setcost( 2 )
+
+-- Sets the ACF fuel tank refuel duty status, which supplies fuel to other fuel tanks
+e2function void entity:acfRefuelDuty(number on)
+ if not isFuel(this) then return end
+ if not isOwner(self, this) then return end
+ this:TriggerInput("Refuel Duty", on)
+end
+
+__e2setcost( 10 )
+
+-- Returns the remaining liters or kilowatt hours of fuel in an ACF fuel tank or engine
+e2function number entity:acfFuel()
+ if isFuel(this) then
+ if restrictInfo(self, this) then return 0 end
+ return math.Round(this.Fuel, 3)
+ elseif isEngine(this) then
+ if restrictInfo(self, this) then return 0 end
+ if not #(this.FuelLink) then return 0 end --if no tanks, return 0
+
+ local liters = 0
+ for _,tank in pairs(this.FuelLink) do
+ if not validPhysics(tank) then continue end
+ if tank.Active then liters = liters + tank.Fuel end
+ end
+
+ return math.Round(liters, 3)
+ end
+ return 0
+end
+
+-- Returns the amount of fuel in an ACF fuel tank or linked to engine as a percentage of capacity
+e2function number entity:acfFuelLevel()
+ if isFuel(this) then
+ if restrictInfo(self, this) then return 0 end
+ return math.Round(this.Fuel / this.Capacity, 3)
+ elseif isEngine(this) then
+ if restrictInfo(self, this) then return 0 end
+ if not #(this.FuelLink) then return 0 end --if no tanks, return 0
+
+ local liters = 0
+ local capacity = 0
+ for _,tank in pairs(this.FuelLink) do
+ if not validPhysics(tank) then continue end
+ if tank.Active then
+ capacity = capacity + tank.Capacity
+ liters = liters + tank.Fuel
+ end
+ end
+ if not (capacity > 0) then return 0 end
+
+ return math.Round(liters / capacity, 3)
+ end
+ return 0
+end
+
+-- Returns the current fuel consumption in liters per minute or kilowatts of an engine
+e2function number entity:acfFuelUse()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not #(this.FuelLink) then return 0 end --if no tanks, return 0
+
+ local Tank = nil
+ for _,fueltank in pairs(this.FuelLink) do
+ if not validPhysics(fueltank) then continue end
+ if fueltank.Fuel > 0 and fueltank.Active then Tank = fueltank break end
+ end
+ if not Tank then return 0 end
+
+ local Consumption
+ if this.FuelType == "Electric" then
+ Consumption = 60 * (this.Torque * this.FlyRPM / 9548.8) * this.FuelUse
+ else
+ local Load = 0.3 + this.Throttle * 0.7
+ Consumption = 60 * Load * this.FuelUse * (this.FlyRPM / this.PeakKwRPM) / ACF.FuelDensity[Tank.FuelType]
+ end
+ return math.Round(Consumption, 3)
+end
+
+-- Returns the peak fuel consumption in liters per minute or kilowatts of an engine at powerband max, for the current fuel type the engine is using
+e2function number entity:acfPeakFuelUse()
+ if not isEngine(this) then return 0 end
+ if restrictInfo(self, this) then return 0 end
+ if not #(this.FuelLink) then return 0 end --if no tanks, return 0
+
+ local fuel = "Petrol"
+ local Tank = nil
+ for _,fueltank in pairs(this.FuelLink) do
+ if fueltank.Fuel > 0 and fueltank.Active then Tank = fueltank break end
+ end
+ if tank then fuel = tank.Fuel end
+
+ local Consumption
+ if this.FuelType == "Electric" then
+ Consumption = 60 * (this.PeakTorque * this.LimitRPM / (4*9548.8)) * this.FuelUse
+ else
+ local Load = 0.3 + this.Throttle * 0.7
+ Consumption = 60 * this.FuelUse / ACF.FuelDensity[fuel]
+ end
+ return math.Round(Consumption, 3)
+end
+
+
diff --git a/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua b/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua
new file mode 100644
index 000000000..b4964e6a4
--- /dev/null
+++ b/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua
@@ -0,0 +1,105 @@
+--general
+E2Helper.Descriptions["acfIsEngine"] = "Returns 1 if the entity is an ACF engine."
+E2Helper.Descriptions["acfIsGearbox"] = "Returns 1 if the entity is an ACF gearbox."
+E2Helper.Descriptions["acfIsGun"] = "Returns 1 if the entity is an ACF gun."
+E2Helper.Descriptions["acfIsAmmo"] = "Returns 1 if the entity is an ACF ammo crate."
+E2Helper.Descriptions["acfIsFuel"] = "Returns 1 if the entity is an ACF fuel tank."
+E2Helper.Descriptions["acfActive"] = "Gets/sets Active (0-1) for an ACF engine, ammo crate, or fuel tank."
+E2Helper.Descriptions["acfHitClip"] = "Returns 1 if hitpos is on a clipped part of prop"
+E2Helper.Descriptions["acfNameShort"] = "Returns the short name of an ACF entity."
+E2Helper.Descriptions["acfName"] = "Returns the full name of an ACF entity."
+E2Helper.Descriptions["acfType"] = "Returns the type of ACF entity."
+E2Helper.Descriptions["acfLinkTo"] = "Link various ACF components together."
+E2Helper.Descriptions["acfUnlinkFrom"] = "Unlink various ACF components."
+E2Helper.Descriptions["acfCapacity"] = "Returns the capacity of an ACF ammo crate or fuel tank."
+E2Helper.Descriptions["acfInfoRestricted"] = "Returns 1 if functions returning sensitive info are restricted to owned props."
+E2Helper.Descriptions["acfLinks"] = "Returns all the entities which are linked to this entity through ACF."
+E2Helper.Descriptions["acfGetLinkedWheels"] = "Returns any wheels linked to this engine/gearbox or its children links."
+E2Helper.Descriptions["acfDragDiv"] = "Returns current ACF drag divisor"
+
+--engine
+E2Helper.Descriptions["acfMaxTorque"] = "Returns the maximum torque (in N/m) of an ACF engine."
+E2Helper.Descriptions["acfMaxPower"] = "Returns the maximum power (in kW) of an ACF engine."
+E2Helper.Descriptions["acfMaxTorqueWithFuel"] = "Returns the maximum torque (in N/m) of an ACF engine with fuel linked."
+E2Helper.Descriptions["acfMaxPowerWithFuel"] = "Returns the maximum power (in kW) of an ACF engine with fuel linked."
+E2Helper.Descriptions["acfIdleRPM"] = "Returns the idle RPM of an ACF engine."
+E2Helper.Descriptions["acfPowerbandMin"] = "Returns the powerband minimum of an ACF engine."
+E2Helper.Descriptions["acfPowerbandMax"] = "Returns the powerband maximum of an ACF engine."
+E2Helper.Descriptions["acfRedline"] = "Returns the redline RPM of an ACF engine."
+E2Helper.Descriptions["acfRPM"] = "Returns the current RPM of an ACF engine."
+E2Helper.Descriptions["acfTorque"] = "Returns the current torque (in N/m) of an ACF engine."
+E2Helper.Descriptions["acfFlyInertia"] = "Returns the inertia of an ACF engine's flywheel"
+E2Helper.Descriptions["acfFlyMass"] = "Returns the mass of an ACF engine's flywheel."
+E2Helper.Descriptions["acfPower"] = "Returns the current power (in kW) of an ACF engine."
+E2Helper.Descriptions["acfInPowerband"] = "Returns 1 if the ACF engine RPM is inside the powerband."
+E2Helper.Descriptions["acfThrottle"] = "Gets/sets Throttle (0-100) for an ACF engine."
+
+--gearbox
+E2Helper.Descriptions["acfGear"] = "Returns the current gear of an ACF gearbox."
+E2Helper.Descriptions["acfNumGears"] = "Returns the number of gears of an ACF gearbox."
+E2Helper.Descriptions["acfFinalRatio"] = "Returns the final ratio of an ACF gearbox."
+E2Helper.Descriptions["acfTorqueRating"] = "Returns the maximum torque (in N/m) an ACF gearbox can handle."
+E2Helper.Descriptions["acfIsDual"] = "Returns 1 if an ACF gearbox is dual clutch."
+E2Helper.Descriptions["acfShiftTime"] = "Returns the time in ms an ACF gearbox takes to change gears."
+E2Helper.Descriptions["acfInGear"] = "Returns 1 if an ACF gearbox is in gear."
+E2Helper.Descriptions["acfTotalRatio"] = "Returns the total ratio (current gear * final) of an ACF gearbox."
+E2Helper.Descriptions["acfGearRatio"] = "Returns the ratio of a specified gear of an ACF gearbox."
+E2Helper.Descriptions["acfTorqueOut"] = "Returns the current torque output (in N/m) an ACF gearbox. A bit jumpy due to how ACF applies power."
+E2Helper.Descriptions["acfCVTRatio"] = "Sets the gear ratio of a CVT. Passing 0 causes the CVT to resume using target min/max rpm calculation."
+E2Helper.Descriptions["acfShift"] = "Shift to the specified gear for an ACF gearbox."
+E2Helper.Descriptions["acfShiftUp"] = "Set an ACF gearbox to shift up."
+E2Helper.Descriptions["acfShiftDown"] = "Set an ACF gearbox to shift down."
+E2Helper.Descriptions["acfBrake"] = "Sets the brake for an ACF gearbox. Sets both sides of a dual clutch gearbox."
+E2Helper.Descriptions["acfBrakeLeft"] = "Sets the left brake for an ACF gearbox. Only works for dual clutch."
+E2Helper.Descriptions["acfBrakeRight"] = "Sets the right brake for an ACF gearbox. Only works for dual clutch."
+E2Helper.Descriptions["acfClutch"] = "Sets the clutch for an ACF gearbox. Sets both sides of a dual clutch gearbox."
+E2Helper.Descriptions["acfClutchLeft"] = "Sets the left clutch for an ACF gearbox. Only works for dual clutch."
+E2Helper.Descriptions["acfClutchRight"] = "Sets the right clutch for an ACF gearbox. Only works for dual clutch."
+E2Helper.Descriptions["acfSteerRate"] = "Sets the steer ratio for an ACF double differential gearbox."
+E2Helper.Descriptions["acfHoldGear"] = "Set to 1 to stop ACF automatic gearboxes upshifting."
+E2Helper.Descriptions["acfShiftPointScale"] = "Sets the shift point scale for an ACF automatic gearbox."
+
+--guns
+E2Helper.Descriptions["acfIsReloading"] = "Returns 1 if an ACF weapon is reloading."
+E2Helper.Descriptions["acfReady"] = "Returns 1 if an ACF weapon is ready to fire."
+E2Helper.Descriptions["acfMagSize"] = "Returns the magazine capacity of an ACF weapon."
+E2Helper.Descriptions["acfMagfReloadTime"] = "Returns time it takes for an ACF weapon to reload magazine."
+E2Helper.Descriptions["acfReloadTime"] = "Returns time to next shot of an ACF weapon."
+E2Helper.Descriptions["acfReloadProgress"] = "Returns number between 0 and 1 which represents reloading progress of an ACF weapon. Useful for progress bars."
+E2Helper.Descriptions["acfSpread"] = "Returns the spread of an ACF weapon."
+E2Helper.Descriptions["acfFireRate"] = "Returns the rate of fire of an ACF weapon."
+E2Helper.Descriptions["acfFire"] = "Sets the firing state of an ACF weapon. Kills are only attributed to gun owner. Use wire inputs on gun if you want to properly attribute kills to driver."
+E2Helper.Descriptions["acfUnload"] = "Causes an ACF weapon to unload."
+E2Helper.Descriptions["acfReload"] = "Causes an ACF weapon to reload."
+E2Helper.Descriptions["acfMagRounds"] = "Returns the rounds remaining in the magazine of an ACF weapon."
+E2Helper.Descriptions["acfAmmoCount"] = "Returns the number of rounds in active ammo crates linked to an ACF weapon."
+E2Helper.Descriptions["acfTotalAmmoCount"] = "Returns the number of rounds in all ammo crates linked to an ACF weapon."
+
+--ammo
+E2Helper.Descriptions["acfRounds"] = "Returns the number of rounds in an ACF ammo crate."
+E2Helper.Descriptions["acfAmmoType"] = "Returns the type of ammo in an ACF ammo crate or ACF weapon."
+E2Helper.Descriptions["acfRoundType"] = "Returns the type of weapon the ammo in an ACF ammo crate loads into."
+E2Helper.Descriptions["acfCaliber"] = "Returns the caliber of the weapon or ammo."
+E2Helper.Descriptions["acfMuzzleVel"] = "Returns the muzzle velocity of the ammo in an ACF ammo crate or weapon."
+E2Helper.Descriptions["acfProjectileMass"] = "Returns the mass of the projectile in an ACF ammo crate or weapon."
+E2Helper.Descriptions["acfFLSpikes"] = "Returns the number of projectiles in a flechette round."
+E2Helper.Descriptions["acfFLSpikeRadius"] = "Returns the radius (in mm) of the spikes in a flechette round."
+E2Helper.Descriptions["acfFLSpikeMass"] = "Returns the mass of a single spike in a FL round in a crate or gun."
+E2Helper.Descriptions["acfPenetration"] = "Returns the penetration of an AP, APHE, HEAT or FL round in an ACF ammo crate or weapon."
+E2Helper.Descriptions["acfBlastRadius"] = "Returns the blast radius of an HE, APHE, or HEAT round in an ACF ammo crate or weapon."
+
+--armor
+E2Helper.Descriptions["acfPropHealth"] = "Returns the current health of an entity."
+E2Helper.Descriptions["acfPropHealthMax"] = "Returns the max health of an entity."
+E2Helper.Descriptions["acfPropArmor"] = "Returns the current armor of an entity."
+E2Helper.Descriptions["acfPropArmorMax"] = "Returns the max armor of an entity."
+E2Helper.Descriptions["acfPropDuctility"] = "Returns the ductility of an entity."
+E2Helper.Descriptions["acfEffectiveArmor"] = "Returns the effective armor of a given nominal armor value and angle, or from a trace hitting an entity."
+
+--fuel
+E2Helper.Descriptions["acfFuel"] = "Returns the remaining liters of fuel or kilowatt hours in an ACF fuel tank, or available to an engine."
+E2Helper.Descriptions["acfFuelLevel"] = "Returns the percent remaining fuel in an ACF fuel tank, or available to an engine."
+E2Helper.Descriptions["acfFuelRequired"] = "Returns 1 if an ACF engine requires fuel."
+E2Helper.Descriptions["acfRefuelDuty"] = "Sets an ACF fuel tank on refuel duty, causing it to supply other fuel tanks with fuel."
+E2Helper.Descriptions["acfFuelUse"] = "Returns the current fuel consumption of an engine in liters per minute or kilowatts."
+E2Helper.Descriptions["acfPeakFuelUse"] = "Returns the peak fuel consumption of an engine in liters per minute or kilowatts."
diff --git a/lua/expadv/components/custom/acf.lua b/lua/expadv/components/custom/acf.lua
new file mode 100644
index 000000000..cc403be94
--- /dev/null
+++ b/lua/expadv/components/custom/acf.lua
@@ -0,0 +1,575 @@
+--[[
+ Based on https://github.com/nrlulz/ACF/blob/master/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua
+ Credits goes to the original authors Fervidusletum and Bubbus.
+--]]
+
+if !WireLib or !ACF then -- Also make sure ACF is actually installed.
+ print("Armored Combat Framework not detected when installing EA2 ACF component, not installing!")
+ return
+end
+
+local Component = EXPADV.AddComponent( "acf", true )
+
+Component.Author = "FreeFry"
+Component.Description = "Adds functions for controlling ACF sents."
+
+Component.restrictInfo = function (ply, ent) -- Hack, this allows this function to be used from inline and prepared type functions.
+ if GetConVar("sbox_acf_restrictinfo"):GetInt() != 0 then
+ if EXPADV.IsOwner(ent, ply) then return false else return true end
+ end
+ return false
+end
+
+Component.linkTables =
+{ -- link resources within each ent type. should point to an ent: true if adding link.Ent, false to add link itself
+ acf_engine = {GearLink = true, FuelLink = false},
+ acf_gearbox = {WheelLink = true, Master = false},
+ acf_fueltank = {Master = false},
+ acf_gun = {AmmoLink = false},
+ acf_ammo = {Master = false}
+}
+
+Component.getLinks = function(ent, enttype)
+ local ret = {}
+ -- find the link resources available for this ent type
+ for entry, mode in pairs(Component.linkTables[enttype]) do
+ if not ent[entry] then error("Couldn't find link resource " .. entry .. " for entity " .. tostring(ent)) return end
+
+ -- find all the links inside the resources
+ for _, link in pairs(ent[entry]) do
+ ret[#ret+1] = mode and link.Ent or link
+ end
+ end
+
+ return ret
+end
+
+Component.searchForGearboxLinks = function(ent)
+ local boxes = ents.FindByClass("acf_gearbox")
+
+ local ret = {}
+
+ for _, box in pairs(boxes) do
+ if IsValid(box) then
+ for _, link in pairs(box.WheelLink) do
+ if link.Ent == ent then
+ ret[#ret+1] = box
+ break
+ end
+ end
+ end
+ end
+
+ return ret
+end
+
+-- [ General Functions ] --
+
+EXPADV.ServerOperators()
+
+Component:AddInlineFunction( "acfInfoRestricted", "", "b" , "$GetConVar('sbox_acf_restrictinfo'):GetBool() or true" )
+Component:AddFunctionHelper( "acfInfoRestricted", "", "Returns true if functions returning sensitive info are restricted to owned props." )
+
+Component:AddPreparedFunction( "acfNameShort", "e:", "s",
+[[@define ret = ""
+if @value 1:IsValid() then
+ if @value 1:GetClass() == "acf_engine" or @value 1:GetClass() == "acf_gearbox" or @value 1:GetClass() == "acf_gun" then
+ @ret = @value 1.Id
+ elseif @value 1:GetClass() == "acf_ammo" then
+ @ret = @value 1.RoundId
+ elseif @value 1:GetClass() == "acf_fueltank" then
+ @ret = @value 1.FuelType
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfNameShort", "e:", "Returns the short name of an ACF entity." )
+
+Component:AddInlineFunction( "acfCapacity", "e:", "n", "((@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_fueltank')) and @value 1.Capacity or 0)" )
+Component:AddFunctionHelper( "acfCapacity", "e:", "Returns the capacity of an ACF ammo crate or fuel tank." )
+
+Component:AddInlineFunction( "acfActive", "e:", "b", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and (@value 1:GetClass() == 'acf_engine' or @value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_fueltank') and @value 1.Active or false)" )
+Component:AddFunctionHelper( "acfActive", "e:", "Returns true if an ACF engine, ammo crate, or fuel tank is active." )
+
+Component:AddPreparedFunction( "acfActive", "e:b", "",
+[[if EXPADV.IsOwner(@value 1, Context.player) and (@value 1:GetClass() == "acf_engine" or @value 1:GetClass() == "acf_ammo" or @value 1:GetClass() == "acf_fueltank") then
+ if @value 2 then
+ @value 1:TriggerInput( "Active", 1 )
+ else
+ @value 1:TriggerInput( "Active", 0 )
+ end
+end]] )
+Component:AddFunctionHelper( "acfActive", "e:b", "Sets Active (false/true) for an ACF engine, ammo crate, or fuel tank." )
+
+Component:AddInlineFunction( "acfHitClip", "e:v", "b", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1)) and ACF_CheckClips(@value 1, @value 2)" )
+Component:AddFunctionHelper( "acfHitClip", "e:v", "Returns true if hitpos is on a clipped part of prop." )
+
+Component:AddPreparedFunction( "acfLinks", "e:", "ar",
+[[@define ret = { __type = "e" }
+if @value 1:IsValid() then
+ if not EXPADV.Components.acf.linkTables[@value 1:GetClass()] then
+ @ret = EXPADV.Components.acf.searchForGearboxLinks(@value 1)
+ @ret.__type = "e"
+ else
+ @ret = EXPADV.Components.acf.getLinks(@value 1, @value 1:GetClass())
+ @ret.__type = "e"
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfLinks", "e:", "Returns all the entities which are linked to this entity through ACF." )
+
+Component:AddPreparedFunction( "acfName", "e:", "s",
+[[@define ret = ""
+if @value 1:IsValid() then
+ if @value 1:GetClass() == "acf_ammo" then
+ @ret = @value 1.RoundId .. " " .. @value 1.RoundType
+ elseif @value 1:GetClass() == "acf_fueltank" then
+ @ret = @value 1.FuelType .. " " .. @value 1.SizeId
+ else
+ @define acftype = ""
+ if @value 1:GetClass() == "acf_engine" or @value 1:GetClass() == "acf_gearbox" then
+ @acftype = "Mobility"
+ elseif @value 1:GetClass() == "acf_gun" then
+ @acftype = "Guns"
+ end
+ if @acftype ~= "" then @ret = $list.Get("ACFEnts")[@acftype][@value 1.Id]["name"] or "" end
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfName", "e:", "Returns the full name of an ACF entity." )
+
+Component:AddPreparedFunction( "acfType", "e:", "s",
+[[@define ret = ""
+if @value 1:IsValid() then
+ if @value 1:GetClass() == "acf_engine" or @value 1:GetClass() == "acf_gearbox" then
+ @ret = $list.Get("ACFEnts")["Mobility"][@value 1.Id]["category"] or ""
+ elseif @value 1:GetClass() == "acf_gun" then
+ @ret = $list.Get("ACFClasses")["GunClass"][@value 1.Class]["name"] or ""
+ elseif @value 1:GetClass() == "acf_ammo" then
+ @ret = @value 1.RoundType or ""
+ elseif @value 1:GetClass() == "acf_fueltank" then
+ @ret = @value 1.FuelType or ""
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfType", "e:", "Returns the type of ACF entity." )
+
+-- [ Engine Functions ] --
+Component:AddInlineFunction( "acfIsEngine", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_engine' or false)" )
+Component:AddFunctionHelper( "acfIsEngine", "e:", "Returns true if the entity is an ACF engine." )
+
+Component:AddInlineFunction( "acfMaxTorque", "e:", "n", "(@value 1:IsValid() and @value 1.PeakTorque or 0)")
+Component:AddFunctionHelper( "acfMaxTorque", "e:", "Returns the maximum torque (in N/m) of an ACF engine." )
+
+Component:AddPreparedFunction( "acfMaxPower", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() then
+ if @value 1.iselec then
+ @ret = $math.floor( @value 1.PeakTorque * @value 1.LimitRPM / 38195.2 )
+ else
+ @ret = $math.floor( @value 1.PeakTorque * @value 1.PeakMaxRPM / 9548.8 )
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfMaxPower", "e:", "Returns the maximum power (in kW) of an ACF engine." )
+
+Component:AddInlineFunction( "acfIdleRPM", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_engine' and @value 1.IdleRPM or 0)" )
+Component:AddFunctionHelper( "acfIdleRPM", "e:", "Returns the idle RPM of an ACF engine." )
+
+Component:AddInlineFunction( "acfPowerbandMin", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_engine' and @value 1.PeakMinRPM or 0)" )
+Component:AddFunctionHelper( "acfPowerbandMin", "e:", "Returns the powerband minimum of an ACF engine." )
+
+Component:AddInlineFunction( "acfPowerbandMax", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_engine' and @value 1.PeakMaxRPM or 0)" )
+Component:AddFunctionHelper( "acfPowerbandMax", "e:", "Returns the powerband maximum of an ACF engine." )
+
+Component:AddInlineFunction( "acfRedline", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_engine' and @value 1.LimitRPM or 0)" )
+Component:AddFunctionHelper( "acfRedline", "e:", "Returns the redline RPM of an ACF engine." )
+
+Component:AddInlineFunction( "acfRPM", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_engine' and $math.floor(@value 1.FlyRPM or 0))" )
+Component:AddFunctionHelper( "acfRPM", "e:", "Returns the current RPM of an ACF engine." )
+
+Component:AddInlineFunction( "acfTorque", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_engine' and $math.floor(@value 1.Torque or 0))" )
+Component:AddFunctionHelper( "acfTorque", "e:", "Returns the current torque (in N/m) of an ACF engine." )
+
+Component:AddInlineFunction( "acfPower", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_engine' and $math.floor((@value 1.Torque or 0) * (@value 1.FlyRPM or 0) / 9548.8))" )
+Component:AddFunctionHelper( "acfPower", "e:", "Returns the current power (in kW) of an ACF engine." )
+
+Component:AddInlineFunction( "acfInPowerband", "e:", "b", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_engine' and (@value 1.FlyRPM > @value 1.PeakMinRPM and @value 1.FlyRPM < @value 1.PeakMaxRPM))" )
+Component:AddFunctionHelper( "acfInPowerband", "e:", "Returns true if the ACF engine RPM is inside the powerband." )
+
+Component:AddInlineFunction( "acfThrottle", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_engine' and (@value 1.Throttle or 0) * 100)" )
+Component:AddFunctionHelper( "acfThrottle", "e:", "Returns the current throttle of an ACF engine." )
+
+Component:AddPreparedFunction( "acfThrottle", "e:n", "",
+[[if @value 1:IsValid() and EXPADV.IsOwner(@value 1, Context.player) and @value 1:GetClass() == "acf_engine" then
+ @value 1:TriggerInput( "Throttle", @value 2)
+end]] )
+Component:AddFunctionHelper( "acfThrottle", "e:n", "Sets the throttle of an ACF engine (0-100)." )
+
+-- [ Gearbox Functions ] --
+
+Component:AddInlineFunction( "acfIsGearbox", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gearbox' or false)")
+Component:AddFunctionHelper( "acfIsGearbox", "e:", "Returns true if the entity is an ACF gearbox." )
+
+Component:AddInlineFunction( "acfGear", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.Gear or 0)" )
+Component:AddFunctionHelper( "acfGear", "e:", "Returns the current gear of an ACF gearbox." )
+
+Component:AddInlineFunction( "acfNumGears", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.Gears or 0)" )
+Component:AddFunctionHelper( "acfNumGears", "e:", "Returns the number of gears of an ACF gearbox." )
+
+Component:AddInlineFunction( "acfFinalRatio", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.GearTable['Final'] or 0)" )
+Component:AddFunctionHelper( "acfFinalRatio", "e:", "Returns the final ratio of an ACF gearbox." )
+
+Component:AddInlineFunction( "acfTotalRatio", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.GearRatio or 0)" )
+Component:AddFunctionHelper( "acfTotalRatio", "e:", "Returns the total ratio (current gear * final) of an ACF gearbox." )
+
+Component:AddInlineFunction( "acfTorqueRating", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gearbox' and @value 1.MaxTorque or 0)" )
+Component:AddFunctionHelper( "acfTorqueRating", "e:", "Returns the maximum torque (in N/m) an ACF gearbox can handle." )
+
+Component:AddInlineFunction( "acfIsDual", "e:", "b", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.Dual or false)" )
+Component:AddFunctionHelper( "acfIsDual", "e:", "Returns true if an ACF gearbox is dual clutch." )
+
+Component:AddInlineFunction( "acfShiftTime", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gearbox' and (@value 1.SwitchTime or 0) * 1000 or 0)" )
+Component:AddFunctionHelper( "acfShiftTime", "e:", "Returns the time in ms an ACF gearbox takes to chance gears." )
+
+Component:AddInlineFunction( "acfInGear", "e:", "b", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.InGear or false)" )
+Component:AddFunctionHelper( "acfInGear", "e:", "Returns true if an ACF gearbox is in gear." )
+
+Component:AddInlineFunction( "acfGearRatio", "e:n", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.GearTable[$math.Clamp($math.floor(@value 2), 1, @value 1.Gears or 1)] or 0)" )
+Component:AddFunctionHelper( "acfGearRatio", "e:n", "Returns the ratio of the specified gear of an ACF gearbox." )
+
+Component:AddInlineFunction( "acfTorqueOut", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and $math.min(@value 1.TotalReqTq or 0, @value 1.MaxTorque or 0) / (@value 1.GearRatio or 1) or 0)" )
+Component:AddFunctionHelper( "acfTorqueOut", "e:", "Returns the current torque output (in N/m) of an ACF gearbox (not precise, due to how ACF applies power)." )
+
+Component:AddPreparedFunction( "acfCVTRatio", "e:n", "",
+[[if @value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1:GetClass() == 'acf_gearbox' and @value 1.CVT then
+ @value 1.CVTRatio = $math.Clamp(@value 2, 0, 1)
+end]] )
+Component:AddFunctionHelper( "acfCVTRatio", "e:n", "Sets the gear ratio of a CVT. Passing 0 causes the CVT to resume using target min/max RPM calculation." )
+
+Component:AddPreparedFunction( "acfShift", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1:TriggerInput( "Gear", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfShift", "e:n", "Tells an ACF gearbox to shift to the specified gear." )
+
+Component:AddPreparedFunction( "acfShiftUp", "e:", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1:TriggerInput( "Gear Up", 1 )
+end]] )
+Component:AddFunctionHelper( "acfShiftUp", "e:", "Tells an ACF gearbox to shift up." )
+
+Component:AddPreparedFunction( "acfShiftDown", "e:", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1:TriggerInput( "Gear Down", 1 )
+end]] )
+Component:AddFunctionHelper( "acfShiftDown", "e:", "Tells an ACF gearbox to shift down." )
+
+Component:AddPreparedFunction( "acfBrake", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1:TriggerInput( "Brake", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfBrake", "e:n", "Sets the brake for an ACF gearbox. Sets both sides of a dual clutch gearbox." )
+
+Component:AddPreparedFunction( "acfBrakeLeft", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.Dual then
+ @value 1:TriggerInput( "Left Brake", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfBrakeLeft", "e:n", "Sets the left brake for an ACF gearbox. Only works on a dual clutch gearbox." )
+
+Component:AddPreparedFunction( "acfBrakeRight", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.Dual then
+ @value 1:TriggerInput( "Right Brake", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfBrakeRight", "e:n", "Sets the right brake for an ACF gearbox. Only works on a dual clutch gearbox." )
+
+Component:AddPreparedFunction( "acfClutch", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1:TriggerInput( "Clutch", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfClutch", "e:n", "Sets the clutch for an ACF gearbox. Sets both sides of a dual clutch gearbox." )
+
+Component:AddPreparedFunction( "acfClutchLeft", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.Dual then
+ @value 1:TriggerInput( "Left Clutch", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfClutchLeft", "e:n", "Sets the left clutch for an ACF gearbox. Only works on a dual clutch gearbox." )
+
+Component:AddPreparedFunction( "acfClutchRight", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.Dual then
+ @value 1:TriggerInput( "Right Clutch", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfClutchRight", "e:n", "Sets the right clutch for an ACF gearbox. Only works on a dual clutch gearbox." )
+
+Component:AddPreparedFunction( "acfSteerRate", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.DoubleDiff then
+ @value 1:TriggerInput( "Steer Rate", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfSteerRate", "e:n", "Sets the steer rate of a ACF gearbox. Only works on a dual differential." )
+
+Component:AddPreparedFunction( "acfHoldGear", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.Auto then
+ @value 1:TriggerInput( "Hold Gear", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfHoldGear", "e:n", "Set to 1 to stop ACF automatic gearboxes upshifting." )
+
+Component:AddPreparedFunction( "acfShiftPointScale", "e:n", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gearbox" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.Auto then
+ @value 1:TriggerInput( "Shift Speed Scale", @value 2 )
+end]] )
+Component:AddFunctionHelper( "acfShiftPointScale", "e:n", "Sets the shift point scale for an ACF automatic gearbox." )
+
+-- [ Gun Functions ] --
+
+Component:AddInlineFunction( "acfIsGun", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gun' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) or false)" )
+Component:AddFunctionHelper( "acfIsGun", "e:", "Returns true if the entity is an ACF weapon." )
+
+Component:AddInlineFunction( "acfReady", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gun' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.Ready or false)" )
+Component:AddFunctionHelper( "acfReady", "e:", "Returns true if an ACF weapon is ready to fire." )
+
+Component:AddInlineFunction( "acfMagSize", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gun' and @value 1.MagSize or 0)" )
+Component:AddFunctionHelper( "acfMagSize", "e:", "Returns the magazine capacity of an ACF weapon." )
+
+Component:AddPreparedFunction( "acfSpread", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and (@value 1:GetClass() == "acf_gun" or @value 1:GetClass() == "acf_ammo") and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) then
+ @ret = @value 1.GetInaccuracy and @value 1:GetInaccuracy() or @value 1.Inaccuracy or 0
+ if @value 1.BulletData["Type"] == "FL" then
+ @ret = @ret + (@value 1.BulletData["FlechetteSpread"] or 0)
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfSpread", "e:", "Returns the spread of an ACF weapon." )
+
+Component:AddInlineFunction( "acfIsReloading", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gun' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.Reloading or false)" )
+Component:AddFunctionHelper( "acfIsReloading", "e:", "Returns true if an ACF weapon is reloading." )
+
+Component:AddInlineFunction( "acfFireRate", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_gun' and $math.Round(@value 1.RateOfFire or 0, 3) or 0)" )
+Component:AddFunctionHelper( "acfFireRate", "e:", "Returns the rate of fire of an ACF weapon." )
+
+Component:AddPreparedFunction( "acfMagRounds", "e:", "n",
+[[@define ret = 0
+ if @value 1:IsValid() and @value 1:GetClass() == 'acf_gun' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) then
+ if @value 1.MagSize and @value 1.CurrentShot and @value 1.MagSize > 1 then
+ @ret = (@value 1.MagSize - @value 1.CurrentShot) or 1
+ else
+ @ret = @value 1.Ready or 0
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfMagRounds", "e:", "Returns the remaining rounds in the magazine of an ACF weapon." )
+
+Component:AddPreparedFunction( "acfFire", "e:b", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gun" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1:TriggerInput( "Fire", @value 2 and 1 or 0)
+end]] )
+Component:AddFunctionHelper( "acfFire", "e:b", "Sets the firing state of an ACF weapon. Kills are only attributed to gun owner. Use wire inputs on a gun if you want to properly attribute kills to driver." )
+
+Component:AddPreparedFunction( "acfUnload", "e:", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gun" and EXPADV.IsOwner(@value 1, Context.player) and @value 1.UnloadAmmo then
+ @value 1:UnloadAmmo()
+end]] )
+Component:AddFunctionHelper( "acfUnload", "e:", "Causes an ACF weapon to unload." )
+
+Component:AddPreparedFunction( "acfReload", "e:", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_gun" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1.Reloading = true
+end]] )
+Component:AddFunctionHelper( "acfReload", "e:", "Causes an ACF weapon to reload." )
+
+Component:AddPreparedFunction( "acfAmmoCount", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and @value 1:GetClass() == "acf_gun" and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.AmmoLink then
+ for _, AmmoEnt in pairs(@value 1.AmmoLink) do
+ if AmmoEnt and AmmoEnt:IsValid() and AmmoEnt["Load"] then
+ @ret = @ret + (AmmoEnt.Ammo or 0)
+ end
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfAmmoCount", "e:", "Returns the number of rounds in active ammo crates linked to an ACF weapon." )
+
+Component:AddPreparedFunction( "acfTotalAmmoCount", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and @value 1:GetClass() == "acf_gun" and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.AmmoLink then
+ for _, AmmoEnt in pairs(@value 1.AmmoLink) do
+ if AmmoEnt and AmmoEnt:IsValid() then
+ @ret = @ret + (AmmoEnt.Ammo or 0)
+ end
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfTotalAmmoCount", "e:", "Returns the number of rounds in all ammo crates linked to an ACF weapon." )
+
+-- [ Ammo Functions ] --
+
+Component:AddInlineFunction( "acfIsAmmo", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_ammo' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) or false)" )
+Component:AddFunctionHelper( "acfIsAmmo", "e:", "Returns true if the entity is an ACF ammo crate." )
+
+Component:AddInlineFunction( "acfRounds", "e:", "n", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_ammo' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.Ammo or 0)" )
+Component:AddFunctionHelper( "acfRounds", "e:", "Returns the number of rounds in an ACF ammo crate." )
+
+Component:AddInlineFunction( "acfRoundType", "e:", "s", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_ammo' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.RoundId or '')" )
+Component:AddFunctionHelper( "acfRoundType", "e:", "Returns the type of weapon the ammo in an ACF ammo crate loads into." )
+
+Component:AddInlineFunction( "acfAmmoType", "e:", "s", "(@value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.BulletData['Type'] or '')" )
+Component:AddFunctionHelper( "acfAmmoType", "e:", "Returns the type of ammo in an ACF ammo crate or ACF weapon." )
+
+Component:AddInlineFunction( "acfCaliber", "e:", "n", "(@value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and (@value 1.Caliber or 0) * 10 or 0)" )
+Component:AddFunctionHelper( "acfCaliber", "e:", "Returns the caliber of the ammo in an ACF ammo crate or weapon." )
+
+Component:AddInlineFunction( "acfMuzzleVel", "e:", "n", "(@value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and $math.Round((@value 1.BulletData['MuzzleVel'] or 0) * $ACF.VelScale, 3) or 0)" )
+Component:AddFunctionHelper( "acfMuzzleVel", "e:", "Returns the muzzle velocity of the ammo in an ACF ammo crate or weapon." )
+
+Component:AddInlineFunction( "acfProjectileMass", "e:", "n", "(@value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and $math.Round(@value 1.BulletData['ProjMass'] or 0, 3) or 0)" )
+Component:AddFunctionHelper( "acfProjectileMass", "e:", "Returns the mass of the projectile in an ACF ammo crate or weapon." )
+
+Component:AddInlineFunction( "acfFLSpikes", "e:", "n", "(@value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.BulletData['Type'] == 'FL' and @value 1.BulletData['Flechettes'] or 0)" )
+Component:AddFunctionHelper( "acfFLSpikes", "e:", "Returns the number of projectiles in a flechette round in an ACF ammo crate or weapon." )
+
+Component:AddInlineFunction( "acfFLSpikeMass", "e:", "n", "(@value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.BulletData['Type'] == 'FL' and $math.Round(@value 1.BulletData['FlechetteMass'] or 0, 3) or 0)" )
+Component:AddFunctionHelper( "acfFLSpikeMass", "e:", "Returns the mass of a single spike in a flechette round in an ACF ammo crate or weapon. " )
+
+Component:AddInlineFunction( "acfFLSpikeRadius", "e:", "n", "(@value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.BulletData['Type'] == 'FL' and $math.Round((@value 1.BulletData['FlechetteRadius'] or 0), 3) * 10 or 0)" )
+Component:AddFunctionHelper( "acfFLSpikeRadius", "e:", "Returns the radius (in mm) of the spikes in a flechette round in an ACF ammo crate or weapon." )
+
+Component:AddPreparedFunction( "acfPenetration", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) then
+ @define type = @value 1.BulletData["Type"] or ""
+ if @type == "AP" or @type == "APHE" then
+ @ret = $math.Round(( $ACF_Kinetic( @value 1.BulletData["MuzzleVel"]*39.37, @value 1.BulletData["ProjMass"] - (@value 1.BulletData["FillerMass"] or 0), @value 1.BulletData["LimitVel"] ).Penetration / @value 1.BulletData['PenAera'] ) * $ACF.KEtoRHA, 3 )
+ elseif @type == "HEAT" then
+ @ret = $math.Round(( $ACF_Kinetic( @value 1.BulletData["SlugMV"]*39.37, @value 1.BulletData["SlugMass"], 99999999 ).Penetration / @value 1.BulletData["SlugPenAera"] ) * $ACF.KEtoRHA, 3 )
+ elseif @type == "FL" then
+ @ret = $math.Round(( $ACF_Kinetic( @value 1.BulletData["MuzzleVel"]*39.37, @value 1.BulletData["FlechetteMass"], @value 1.BulletData["LimitVel"] ).Penetration / @value 1.BulletData["FlechettePenArea"] ) * $ACF.KEtoRHA, 3 )
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfPenetration", "e:", "Returns the penetration of an AP, APHE, HEAT or FL round in an ACF ammo crate or weapon." )
+
+Component:AddPreparedFunction( "acfBlastRadius", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and (@value 1:GetClass() == 'acf_ammo' or @value 1:GetClass() == 'acf_gun') and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) then
+ @define type = @value 1.BulletData["Type"] or ""
+ if @type == "HE" or @type == "APHE" then
+ @ret = $math.Round( @value 1.BulletData["FillerMass"]^0.33*5, 3 )
+ elseif @type == "HEAT" then
+ @ret = $math.Round( (@value 1.BulletData["FillerMass"]/2)^0.33*5, 3 )
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfBlastRadius", "e:", "Returns the blast radius of an HE, APHE or HEAT round in an ACF ammo crate or weapon." )
+
+-- [ Armor Functions ] --
+
+Component:AddInlineFunction( "acfPropHealth", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and $ACF_Check(@value 1) and $math.Round(@value 1.ACF.Health or 0, 3) or 0)" )
+Component:AddFunctionHelper( "acfPropHealth", "e:", "Returns the current health of an entity." )
+
+Component:AddInlineFunction( "acfPropArmor", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and $ACF_Check(@value 1) and $math.Round(@value 1.ACF.Armour or 0, 3) or 0)" )
+Component:AddFunctionHelper( "acfPropArmor", "e:", "Returns the current armor of an entity." )
+
+Component:AddInlineFunction( "acfPropHealthMax", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and $ACF_Check(@value 1) and $math.Round(@value 1.ACF.MaxHealth or 0, 3) or 0)" )
+Component:AddFunctionHelper( "acfPropHealthMax", "e:", "Returns the current max health of an entity." )
+
+Component:AddInlineFunction( "acfPropArmorMax", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and $ACF_Check(@value 1) and $math.Round(@value 1.ACF.MaxArmour or 0, 3) or 0)" )
+Component:AddFunctionHelper( "acfPropArmorMax", "e:", "Returns the current max armor of an entity." )
+
+Component:AddInlineFunction( "acfPropDuctility", "e:", "n", "(@value 1:IsValid() and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and $ACF_Check(@value 1) and (@value 1.ACF.Ductility or 0) * 100 or 0)" )
+Component:AddFunctionHelper( "acfPropDuctility", "e:", "Returns the ductility of an entity." )
+
+-- [ Fuel Functions ] --
+
+Component:AddInlineFunction( "acfIsFuel", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_fueltank' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) or false)" )
+Component:AddFunctionHelper( "acfIsFuel", "e:", "Returns true if the entity is an ACF fuel tank." )
+
+Component:AddInlineFunction( "acfFuelRequired", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_engine' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.RequiresFuel or false)" )
+Component:AddFunctionHelper( "acfFuelRequired", "e:", "Returns true if an ACF engine requires fuel." )
+
+Component:AddPreparedFunction( "acfRefuelDuty", "e:b", "",
+[[if @value 1:IsValid() and @value 1:GetClass() == "acf_fueltank" and EXPADV.IsOwner(@value 1, Context.player) then
+ @value 1:TriggerInput( "Refuel Duty", @value 2 and 1 or 0)
+end]] )
+Component:AddFunctionHelper( "acfRefuelDuty", "e:b", "Sets an ACF fuel tank on refuel duty, causing it to supply other fuel tanks with fuel." )
+
+Component:AddInlineFunction( "acfRefuelDuty", "e:", "b", "(@value 1:IsValid() and @value 1:GetClass() == 'acf_fueltank' and !EXPADV.Components.acf.restrictInfo(Context.player, @value 1) and @value 1.SupplyFuel or false)" )
+Component:AddFunctionHelper( "acfRefuelDuty", "e:", "Returns true if an ACF fueltank is set on refuel duty." )
+
+Component:AddPreparedFunction( "acfFuel", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and !EXPADV.Components.acf.restrictInfo( Context.player, @value 1 ) then
+ if @value 1:GetClass() == "acf_fueltank" then
+ @ret = $math.Round( @value 1.Fuel or 0, 3 )
+ elseif @value 1:GetClass() == "acf_engine" and @value 1.FuelLink and #@value 1.FuelLink > 0 then
+ for _, tank in pairs( @value 1.FuelLink ) do
+ if $IsValid( tank ) and tank.Fuel then
+ @ret = @ret + tank.Fuel
+ end
+ end
+ @ret = $math.Round( @ret, 3 )
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfFuel", "e:", "Returns the remaining liters of fuel or kilowatt hours in an ACF fuel tank or available to an engine." )
+
+Component:AddPreparedFunction( "acfFuelLevel", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and !EXPADV.Components.acf.restrictInfo( Context.player, @value 1 ) then
+ if @value 1:GetClass() == "acf_fueltank" then
+ @ret = $math.Round( @value 1.Fuel / @value 1.Capacity, 3 )
+ elseif @value 1:GetClass() == "acf_engine" and @value 1.FuelLink and #@value 1.FuelLink > 0 then
+ @define capacity = 0
+ for _, tank in pairs( @value 1.FuelLink ) do
+ if $IsValid( tank ) and tank.Active then
+ @capacity = @capacity + tank.Capacity
+ @ret = @ret + tank.Fuel
+ end
+ end
+ @ret = $math.Round( @ret / @capacity, 3 )
+ end
+end]], "@ret" )
+Component:AddFunctionHelper( "acfFuelLevel", "e:", "Returns the percent of remaining fuel in an ACF fuel tank or available to an engine." )
+
+Component:AddPreparedFunction( "acfFuelUse", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and @value 1:GetClass() == "acf_engine" and @value 1.FuelLink and #@value 1.FuelLink > 0 and !EXPADV.Components.acf.restrictInfo( Context.player, @value 1 ) and @value 1.FuelType then
+ if @value 1.FuelType == "Electric" then
+ @ret = 60 * ( @value 1.Torque * @value 1.FlyRPM / 9548.8 ) * @value 1.FuelUse
+ elseif @value 1.FuelType == "Petrol" or @value 1.FuelType == "Diesel" then
+ @ret = 60 * ( 0.3 + @value 1.Throttle * 0.7 ) * @value 1.FuelUse * ( @value 1.FlyRPM / @value 1.PeakKwRPM ) / $ACF.FuelDensity[@value 1.FuelType]
+ else
+ @define tank = nil
+ for _, fueltank in pairs( @value 1.FuelLink ) do
+ if $IsValid( fueltank ) and fueltank.Fuel > 0 and fueltank.Active then
+ @tank = fueltank
+ break
+ end
+ end
+ if @tank then
+ if @value 1.FuelType == "Electric" then
+ @ret = 60 * ( @value 1.Torque * @value 1.FlyRPM / 9548.8 ) * @value 1.FuelUse
+ else
+ @ret = 60 * ( 0.3 + @value 1.Throttle * 0.7 ) * @value 1.FuelUse * ( @value 1.FlyRPM / @value 1.PeakKwRPM ) / $ACF.FuelDensity[@tank.FuelType]
+ end
+ end
+ end
+ @ret = $math.Round( @ret, 3 )
+end]], "@ret" )
+Component:AddFunctionHelper( "acfFuelUse", "e:", "Returns the current fuel consumption of an ACF engine in liters per minute or kilowatt hours." )
+
+Component:AddPreparedFunction( "acfPeakFuelUse", "e:", "n",
+[[@define ret = 0
+if @value 1:IsValid() and @value 1:GetClass() == "acf_engine" and @value 1.FuelLink and #@value 1.FuelLink > 0 and !EXPADV.Components.acf.restrictInfo( Context.player, @value 1 ) and @value 1.FuelType then
+ if @value 1.FuelType == "Electric" then
+ @ret = 60 * ( @value 1.PeakTorque * @value 1.LimitRPM / ( 4*9548.8) ) * @value 1.FuelUse
+ elseif @value 1.FuelType == "Petrol" or @value 1.FuelType == "Diesel" then
+ @ret = 60 * @value 1.FuelUse / $ACF.FuelDensity[@value 1.FuelType]
+ else
+ @define tank = nil
+ for _, fueltank in pairs( @value 1.FuelLink ) do
+ if $IsValid( fueltank ) and fueltank.Fuel > 0 and fueltank.Active then
+ @tank = fueltank
+ break
+ end
+ end
+ if @tank then
+ if @value 1.FuelType == "Electric" then
+ @ret = 60 * ( @value 1.PeakTorque * @value 1.LimitRPM / ( 4*9548.8) ) * @value 1.FuelUse
+ else
+ @ret = 60 * @value 1.FuelUse / $ACF.FuelDensity[@value 1.FuelType]
+ end
+ end
+ end
+ @ret = $math.Round( @ret, 3 )
+end]], "@ret" )
+Component:AddFunctionHelper( "acfPeakFuelUse", "e:", "Returns the peak fuel consumption of an ACF engine in liters per minute or kilowatt hours." )
+
+-- [ Shared Functions ] --
+--EXPADV.SharedOperators()
diff --git a/lua/starfall/libs_sv/acffunctions.lua b/lua/starfall/libs_sv/acffunctions.lua
new file mode 100644
index 000000000..d0a3d1a16
--- /dev/null
+++ b/lua/starfall/libs_sv/acffunctions.lua
@@ -0,0 +1,1199 @@
+-- [ To Do ] --
+
+-- #general
+
+-- #engine
+
+-- #gearbox
+
+-- #gun
+--use an input to set reload manually, to remove timer?
+
+-- #ammo
+
+-- #prop armor
+--get incident armor ?
+--hit calcs ?
+--conversions ?
+
+-- #fuel
+
+-- [ Helper Functions ] --
+
+local function isEngine ( ent )
+ if not validPhysics( ent ) then return false end
+ if ( ent:GetClass() == "acf_engine" ) then return true else return false end
+end
+
+local function isGearbox ( ent )
+ if not validPhysics( ent ) then return false end
+ if ( ent:GetClass() == "acf_gearbox" ) then return true else return false end
+end
+
+local function isGun ( ent )
+ if not validPhysics( ent ) then return false end
+ if ( ent:GetClass() == "acf_gun" ) then return true else return false end
+end
+
+local function isAmmo ( ent )
+ if not validPhysics( ent ) then return false end
+ if ( ent:GetClass() == "acf_ammo" ) then return true else return false end
+end
+
+local function isFuel ( ent )
+ if not validPhysics(ent) then return false end
+ if ( ent:GetClass() == "acf_fueltank" ) then return true else return false end
+end
+
+local function reloadTime(ent)
+ if ent.CurrentShot and ent.CurrentShot > 0 then return ent.ReloadTime end
+ return ent.MagReload
+end
+
+local propProtectionInstalled = FindMetaTable("Entity").CPPIGetOwner and true
+
+local function restrictInfo ( ent )
+ if not propProtectionInstalled then return false end
+ if GetConVar("sbox_acf_restrictinfo"):GetInt() ~= 0 then
+ if ent:CPPIGetOwner() ~= SF.instance.player then return true else return false end
+ end
+ return false
+end
+
+SF.AddHook("postload", function()
+ local ents_metatable = SF.Entities.Metatable
+ local ents_methods = SF.Entities.Methods
+ local wrap, unwrap = SF.Entities.Wrap, SF.Entities.Unwrap
+
+ -- [General Functions ] --
+
+ -- Returns true if functions returning sensitive info are restricted to owned props
+ function ents_methods:acfInfoRestricted ()
+ return GetConVar( "sbox_acf_restrictinfo" ):GetInt() ~= 0
+ end
+
+ -- Returns the short name of an ACF entity
+ function ents_methods:acfNameShort ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isEngine( this ) then return this.Id or "" end
+ if isGearbox( this ) then return this.Id or "" end
+ if isGun( this ) then return this.Id or "" end
+ if isAmmo( this ) then return this.RoundId or "" end
+ if isFuel( this ) then return this.FuelType .. " " .. this.SizeId end
+ end
+
+ -- Returns the capacity of an acf ammo crate or fuel tank
+ function ents_methods:acfCapacity ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isFuel( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return this.Capacity or 1
+ end
+
+ -- Returns true if the acf engine, fuel tank, or ammo crate is active
+ function ents_methods:acfGetActive ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isEngine( this ) or isAmmo( this ) or isFuel( this ) ) then return false end
+ if restrictInfo( this ) then return false end
+ if not isAmmo( this ) then
+ if this.Active then return true end
+ else
+ if this.Load then return true end
+ end
+ return false
+ end
+
+ -- Turns an ACF engine, ammo crate, or fuel tank on or off
+ function ents_methods:acfSetActive ( on )
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isEngine( this ) or isAmmo( this ) or isFuel( this ) ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Active", on and 1 or 0 )
+ end
+
+ --returns 1 if hitpos is on a clipped part of prop
+ function ents_methods:acfHitClip( hitpos )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( hitpos, "vector" )
+ local this = unwrap( self )
+
+ if not isOwner( self, this ) then return false end
+ if ACF_CheckClips( nil, nil, this, hitpos ) then return true else return false end
+ end
+
+ local linkTables =
+ { -- link resources within each ent type. should point to an ent: true if adding link.Ent, false to add link itself
+ acf_engine = { GearLink = true, FuelLink = false },
+ acf_gearbox = { WheelLink = true, Master = false },
+ acf_fueltank = { Master = false },
+ acf_gun = { AmmoLink = false },
+ acf_ammo = { Master = false }
+ }
+
+ local function getLinks ( ent, enttype )
+ local ret = {}
+ -- find the link resources available for this ent type
+ for entry, mode in pairs( linkTables[ enttype ] ) do
+ if not ent[ entry ] then error( "Couldn't find link resource " .. entry .. " for entity " .. tostring( ent ) ) return end
+
+ -- find all the links inside the resources
+ for _, link in pairs( ent[ entry ] ) do
+ ret[ #ret + 1 ] = mode and wrap( link.Ent ) or link
+ end
+ end
+
+ return ret
+ end
+
+ local function searchForGearboxLinks ( ent )
+ local boxes = ents.FindByClass( "acf_gearbox" )
+
+ local ret = {}
+
+ for _, box in pairs( boxes ) do
+ if IsValid( box ) then
+ for _, link in pairs( box.WheelLink ) do
+ if link.Ent == ent then
+ ret[ #ret + 1 ] = wrap( box )
+ break
+ end
+ end
+ end
+ end
+
+ return ret
+ end
+
+ -- Returns the ACF links associated with the entity
+ function ents_methods:acfLinks ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not IsValid( this ) then return {} end
+
+ local enttype = this:GetClass()
+
+ if not linkTables[ enttype ] then
+ return searchForGearboxLinks( this )
+ end
+
+ return getLinks( this, enttype )
+ end
+
+ -- Returns the full name of an ACF entity
+ function ents_methods:acfName ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isAmmo( this ) then return ( this.RoundId .. " " .. this.RoundType) end
+ if isFuel( this ) then return this.FuelType .. " " .. this.SizeId end
+
+ local acftype = ""
+ if isEngine( this ) then acftype = "Mobility" end
+ if isGearbox( this ) then acftype = "Mobility" end
+ if isGun( this ) then acftype = "Guns" end
+ if ( acftype == "" ) then return "" end
+ local List = list.Get( "ACFEnts" )
+ return List[ acftype ][ this.Id ][ "name" ] or ""
+ end
+
+ -- Returns the type of ACF entity
+ function ents_methods:acfType ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isEngine( this ) or isGearbox( this ) then
+ local List = list.Get( "ACFEnts" )
+ return List[ "Mobility" ][ this.Id ][ "category" ] or ""
+ end
+ if isGun( this ) then
+ local Classes = list.Get( "ACFClasses" )
+ return Classes[ "GunClass" ][ this.Class ][ "name" ] or ""
+ end
+ if isAmmo( this ) then return this.RoundType or "" end
+ if isFuel( this ) then return this.FuelType or "" end
+ return ""
+ end
+
+ --perform ACF links
+ function ents_methods:acfLinkTo ( target, notify )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( target, ents_metatable )
+ SF.CheckType( notify, "number" )
+ local this = unwrap( self )
+ local tar = unwrap( target )
+
+ if not ( ( isGun( this ) or isEngine( this ) or isGearbox( this ) ) and ( isOwner( self, this ) and isOwner( self, tar ) ) ) then
+ if notify > 0 then
+ ACF_SendNotify( self.player, 0, "Must be called on a gun, engine, or gearbox you own." )
+ end
+ return 0
+ end
+
+ local success, msg = this:Link( tar )
+ if notify > 0 then
+ ACF_SendNotify( self.player, success, msg )
+ end
+ return success and 1 or 0
+ end
+
+ --perform ACF unlinks
+ function ents_methods:acfUnlinkFrom ( target, notify )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( target, ents_metatable )
+ SF.CheckType( notify, "number" )
+ local this = unwrap( self )
+ local tar = unwrap( target )
+
+ if not ( ( isGun( this ) or isEngine( this ) or isGearbox( this ) ) and ( isOwner( self, this ) and isOwner( self, tar ) ) ) then
+ if notify > 0 then
+ ACF_SendNotify( self.player, 0, "Must be called on a gun, engine, or gearbox you own." )
+ end
+ return 0
+ end
+
+ local success, msg = this:Unlink( tar )
+ if notify > 0 then
+ ACF_SendNotify( self.player, success, msg )
+ end
+ return success and 1 or 0
+ end
+
+
+
+ -- [ Engine Functions ] --
+
+ -- Returns true if the entity is an ACF engine
+ function ents_methods:acfIsEngine ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isEngine( this ) then return true else return false end
+ end
+
+ -- Returns the torque in N/m of an ACF engine
+ function ents_methods:acfMaxTorque ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ return this.PeakTorque or 0
+ end
+
+ -- Returns the power in kW of an ACF engine
+ function ents_methods:acfMaxPower ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ local peakpower
+ if this.iselec then
+ peakpower = math.floor( this.PeakTorque * this.LimitRPM / ( 4 * 9548.8 ) )
+ else
+ peakpower = math.floor( this.PeakTorque * this.PeakMaxRPM / 9548.8 )
+ end
+ return peakpower or 0
+ end
+
+ -- Returns the idle rpm of an ACF engine
+ function ents_methods:acfIdleRPM ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ return this.IdleRPM or 0
+ end
+
+ -- Returns the powerband min of an ACF engine
+ function ents_methods:acfPowerbandMin ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ return this.PeakMinRPM or 0
+ end
+
+ -- Returns the powerband max of an ACF engine
+ function ents_methods:acfPowerbandMax ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ return this.PeakMaxRPM or 0
+ end
+
+ -- Returns the redline rpm of an ACF engine
+ function ents_methods:acfRedline ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ return this.LimitRPM or 0
+ end
+
+ -- Returns the current rpm of an ACF engine
+ function ents_methods:acfRPM ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return math.floor( this.FlyRPM ) or 0
+ end
+
+ -- Returns the current torque of an ACF engine
+ function ents_methods:acfTorque ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return math.floor( this.Torque or 0 )
+ end
+
+ -- Returns the inertia of an ACF engine's flywheel
+ function ents_methods:acfFlyInertia ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return nil end
+ if restrictInfo( this ) then return 0 end
+ return this.Inertia or 0
+ end
+
+ -- Returns the mass of an ACF engine's flywheel
+ function ents_methods:acfFlyMass ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return nil end
+ if restrictInfo( this ) then return 0 end
+ return this.Inertia / ( 3.1416 )^2 or 0
+ end
+
+ --- Returns the current power of an ACF engine
+ function ents_methods:acfPower ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return math.floor( ( this.Torque or 0 ) * ( this.FlyRPM or 0 ) / 9548.8 )
+ end
+
+ -- Returns true if the RPM of an ACF engine is inside the powerband
+ function ents_methods:acfInPowerband ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return false end
+ if restrictInfo( this ) then return false end
+ if ( this.FlyRPM < this.PeakMinRPM ) then return false end
+ if ( this.FlyRPM > this.PeakMaxRPM ) then return false end
+ return true
+ end
+
+ function ents_methods:acfGetThrottle ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return ( this.Throttle or 0 ) * 100
+ end
+
+ -- Sets the throttle value for an ACF engine
+ function ents_methods:acfSetThrottle ( throttle )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( throttle, "number" )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Throttle", throttle )
+ end
+
+
+ -- [ Gearbox Functions ] --
+
+ -- Returns true if the entity is an ACF gearbox
+ function ents_methods:acfIsGearbox ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isGearbox( this ) then return true else return false end
+ end
+
+ -- Returns the current gear for an ACF gearbox
+ function ents_methods:acfGear ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return this.Gear or 0
+ end
+
+ -- Returns the number of gears for an ACF gearbox
+ function ents_methods:acfNumGears ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return this.Gears or 0
+ end
+
+ -- Returns the final ratio for an ACF gearbox
+ function ents_methods:acfFinalRatio ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return this.GearTable[ "Final" ] or 0
+ end
+
+ -- Returns the total ratio (current gear * final) for an ACF gearbox
+ function ents_methods:acfTotalRatio ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return this.GearRatio or 0
+ end
+
+ -- Returns the max torque for an ACF gearbox
+ function ents_methods:acfTorqueRating ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ return this.MaxTorque or 0
+ end
+
+ -- Returns whether an ACF gearbox is dual clutch
+ function ents_methods:acfIsDual ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return false end
+ if restrictInfo( this ) then return false end
+ if this.Dual then return true end
+ return false
+ end
+
+ -- Returns the time in ms an ACF gearbox takes to change gears
+ function ents_methods:acfShiftTime ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ return ( this.SwitchTime or 0 ) * 1000
+ end
+
+ -- Returns true if an ACF gearbox is in gear
+ function ents_methods:acfInGear ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return false end
+ if restrictInfo( this ) then return false end
+ if this.InGear then return true end
+ return false
+ end
+
+ -- Returns the ratio for a specified gear of an ACF gearbox
+ function ents_methods:acfGearRatio ( gear )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( gear, "number" )
+
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ local g = math.Clamp( math.floor( gear ), 1, this.Gears )
+ return this.GearTable[ g ] or 0
+ end
+
+ -- Returns the current torque output for an ACF gearbox
+ function ents_methods:acfTorqueOut ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return 0 end
+ return math.min( this.TotalReqTq or 0, this.MaxTorque or 0 ) / ( this.GearRatio or 1 )
+ end
+
+ -- Sets the gear ratio of a CVT, set to 0 to use built-in algorithm
+ function ents_methods:acfCVTRatio ( ratio )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( ratio, "number" )
+
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.CVT then return end
+ this.CVTRatio = math.Clamp( ratio, 0, 1 )
+ end
+
+ -- Sets the current gear for an ACF gearbox
+ function ents_methods:acfShift ( gear )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( gear, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Gear", gear )
+ end
+
+ -- Cause an ACF gearbox to shift up
+ function ents_methods:acfShiftUp ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Gear Up", 1 ) --doesn't need to be toggled off
+ end
+
+ -- Cause an ACF gearbox to shift down
+ function ents_methods:acfShiftDown ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Gear Down", 1 ) --doesn't need to be toggled off
+ end
+
+ -- Sets the brakes for an ACF gearbox
+ function ents_methods:acfBrake ( brake )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( brake, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput("Brake", brake)
+ end
+
+ -- Sets the left brakes for an ACF gearbox
+ function ents_methods:acfBrakeLeft ( brake )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( brake, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.Dual then return end
+ this:TriggerInput( "Left Brake", brake )
+ end
+
+ -- Sets the right brakes for an ACF gearbox
+ function ents_methods:acfBrakeRight ( brake )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( brake, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.Dual then return end
+ this:TriggerInput("Right Brake", brake )
+ end
+
+ -- Sets the clutch for an ACF gearbox
+ function ents_methods:acfClutch ( clutch )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( clutch, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Clutch", clutch )
+ end
+
+ -- Sets the left clutch for an ACF gearbox
+ function ents_methods:acfClutchLeft( clutch )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( clutch, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.Dual then return end
+ this:TriggerInput( "Left Clutch", clutch )
+ end
+
+ -- Sets the right clutch for an ACF gearbox
+ function ents_methods:acfClutchRight ( clutch )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( clutch, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.Dual then return end
+ this:TriggerInput( "Right Clutch", clutch )
+ end
+
+ -- Sets the steer ratio for an ACF gearbox
+ function ents_methods:acfSteerRate ( rate )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( rate, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.DoubleDiff then return end
+ this:TriggerInput( "Steer Rate", rate )
+ end
+
+ -- Applies gear hold for an automatic ACF gearbox
+ function ents_methods:acfHoldGear( hold )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( hold, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.Auto then return end
+ this:TriggerInput( "Hold Gear", hold )
+ end
+
+ -- Sets the shift point scaling for an automatic ACF gearbox
+ function ents_methods:acfShiftPointScale( scale )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( scale, "number" )
+ local this = unwrap( self )
+
+ if not isGearbox( this ) then return end
+ if restrictInfo( this ) then return end
+ if not this.Auto then return end
+ this:TriggerInput( "Shift Speed Scale", scale )
+ end
+
+
+ -- [ Gun Functions ] --
+
+ -- Returns true if the entity is an ACF gun
+ function ents_methods:acfIsGun ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isGun( this ) and not restrictInfo( this ) then return true else return false end
+ end
+
+ -- Returns true if the ACF gun is ready to fire
+ function ents_methods:acfReady ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return false end
+ if restrictInfo( this ) then return false end
+ if ( this.Ready ) then return true end
+ return false
+ end
+
+ -- Returns the magazine size for an ACF gun
+ function ents_methods:acfMagSize ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return 0 end
+ return this.MagSize or 1
+ end
+
+ -- Returns the spread for an ACF gun or flechette ammo
+ function ents_methods:acfSpread ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) or isAmmo( this ) then return 0 end
+ local Spread = this.GetInaccuracy and this:GetInaccuracy() or this.Inaccuracy or 0
+ if this.BulletData[ "Type" ] == "FL" then
+ if restrictInfo( this ) then return Spread end
+ return Spread + ( this.BulletData[ "FlechetteSpread" ] or 0 )
+ end
+ return Spread
+ end
+
+ -- Returns true if an ACF gun is reloading
+ function ents_methods:acfIsReloading ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return false end
+ if restrictInfo( this ) then return false end
+ if (this.Reloading) then return true end
+ return false
+ end
+
+ -- Returns the rate of fire of an acf gun
+ function ents_methods:acfFireRate ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return 0 end
+ return math.Round( this.RateOfFire or 0, 3 )
+ end
+
+ -- Returns the number of rounds left in a magazine for an ACF gun
+ function ents_methods:acfMagRounds ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if this.MagSize > 1 then
+ return ( this.MagSize - this.CurrentShot ) or 1
+ end
+ if this.Ready then return 1 end
+ return 0
+ end
+
+ -- Sets the firing state of an ACF weapon
+ function ents_methods:acfFire ( fire )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( fire, "number" )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Fire", fire )
+ end
+
+ -- Causes an ACF weapon to unload
+ function ents_methods:acfUnload ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return end
+ if restrictInfo( this ) then return end
+ this:UnloadAmmo()
+ end
+
+ -- Causes an ACF weapon to reload
+ function ents_methods:acfReload ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return end
+ if restrictInfo( this ) then return end
+ this.Reloading = true
+ end
+
+ --Returns the number of rounds in active ammo crates linked to an ACF weapon
+ function ents_methods:acfAmmoCount ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ local Ammo = 0
+ for Key, AmmoEnt in pairs( this.AmmoLink ) do
+ if AmmoEnt and AmmoEnt:IsValid() and AmmoEnt[ "Load" ] then
+ Ammo = Ammo + ( AmmoEnt.Ammo or 0 )
+ end
+ end
+ return Ammo
+ end
+
+ --Returns the number of rounds in all ammo crates linked to an ACF weapon
+ function ents_methods:acfTotalAmmoCount ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isGun( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ local Ammo = 0
+ for Key, AmmoEnt in pairs( this.AmmoLink ) do
+ if AmmoEnt and AmmoEnt:IsValid() then
+ Ammo = Ammo + ( AmmoEnt.Ammo or 0 )
+ end
+ end
+ return Ammo
+ end
+
+ -- Returns time to next shot of an ACF weapon
+ function ents_methods:acfReloadTime ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if restrictInfo( this ) or not isGun( this ) or this.Ready then return 0 end
+ return reloadTime( this )
+ end
+
+ -- Returns number between 0 and 1 which represents reloading progress of an ACF weapon. Useful for progress bars
+ function ents_methods:acfReloadProgress ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if restrictInfo( this ) or not isGun( this ) or this.Ready then return 1 end
+ return math.Clamp( 1 - (this.NextFire - CurTime()) / reloadTime( this ), 0, 1 )
+ end
+
+ -- Returns time it takes for an ACF weapon to reload magazine
+ function ents_methods:acfMagReloadTime ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if restrictInfo( SF.instance.player , this ) or not isGun( this ) or not this.MagReload then return 0 end
+ return this.MagReload
+ end
+
+ -- [ Ammo Functions ] --
+
+ -- Returns true if the entity is an ACF ammo crate
+ function ents_methods:acfIsAmmo ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isAmmo( this ) and not restrictInfo( this ) then return true else return false end
+ end
+
+ -- Returns the rounds left in an acf ammo crate
+ function ents_methods:acfRounds ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isAmmo( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return this.Ammo or 0
+ end
+
+ -- Returns the type of weapon the ammo in an ACF ammo crate loads into
+ function ents_methods:acfRoundType () --cartridge?
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isAmmo( this ) then return "" end
+ if restrictInfo( this ) then return "" end
+ return this.RoundId or ""
+ end
+
+ -- Returns the type of ammo in a crate or gun
+ function ents_methods:acfAmmoType ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isAmmo( this ) or isGun( this ) then return "" end
+ if restrictInfo( this ) then return "" end
+ return this.BulletData[ "Type" ] or ""
+ end
+
+ -- Returns the caliber of an ammo or gun
+ function ents_methods:acfCaliber ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return ( this.Caliber or 0 ) * 10
+ end
+
+ -- Returns the muzzle velocity of the ammo in a crate or gun
+ function ents_methods:acfMuzzleVel ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return math.Round( ( this.BulletData[ "MuzzleVel" ] or 0 ) * ACF.VelScale, 3 )
+ end
+
+ -- Returns the mass of the projectile in a crate or gun
+ function ents_methods:acfProjectileMass ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return math.Round( this.BulletData[ "ProjMass" ] or 0, 3 )
+ end
+
+ -- Returns the number of projectiles in a flechette round
+ function ents_methods:acfFLSpikes ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not this.BulletData[ "Type" ] == "FL" then return 0 end
+ return this.BulletData[ "Flechettes" ] or 0
+ end
+
+ -- Returns the mass of a single spike in a FL round in a crate or gun
+ function ents_methods:acfFLSpikeMass ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not this.BulletData[ "Type" ] == "FL" then return 0 end
+ return math.Round( this.BulletData[ "FlechetteMass" ] or 0, 3)
+ end
+
+ -- Returns the radius of the spikes in a flechette round in mm
+ function ents_methods:acfFLSpikeRadius ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not this.BulletData[ "Type" ] == "FL" then return 0 end
+ return math.Round( ( this.BulletData[ "FlechetteRadius" ] or 0 ) * 10, 3)
+ end
+
+ -- Returns the penetration of an AP, APHE, or HEAT round
+ function ents_methods:acfPenetration ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ local Type = this.BulletData[ "Type" ] or ""
+ local Energy
+ if Type == "AP" or Type == "APHE" then
+ Energy = ACF_Kinetic( this.BulletData[ "MuzzleVel" ] * 39.37, this.BulletData[ "ProjMass" ] - ( this.BulletData[ "FillerMass" ] or 0 ), this.BulletData[ "LimitVel" ] )
+ return math.Round( ( Energy.Penetration / this.BulletData[ "PenAera" ] ) * ACF.KEtoRHA, 3 )
+ elseif Type == "HEAT" then
+ Energy = ACF_Kinetic( this.BulletData[ "SlugMV" ] * 39.37, this.BulletData[ "SlugMass" ], 9999999 )
+ return math.Round( ( Energy.Penetration / this.BulletData[ "SlugPenAera" ] ) * ACF.KEtoRHA, 3 )
+ elseif Type == "FL" then
+ Energy = ACF_Kinetic( this.BulletData[ "MuzzleVel" ] * 39.37 , this.BulletData[ "FlechetteMass" ], this.BulletData[ "LimitVel" ] )
+ return math.Round( ( Energy.Penetration / this.BulletData[ "FlechettePenArea" ] ) * ACF.KEtoRHA, 3 )
+ end
+ return 0
+ end
+
+ -- Returns the blast radius of an HE, APHE, or HEAT round
+ function ents_methods:acfBlastRadius ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ local Type = this.BulletData[ "Type" ] or ""
+ if Type == "HE" or Type == "APHE" then
+ return math.Round( this.BulletData[ "FillerMass" ]^0.33 * 8, 3 )
+ elseif Type == "HEAT" then
+ return math.Round( ( this.BulletData[ "FillerMass" ] / 3)^0.33 * 8, 3 )
+ end
+ return 0
+ end
+
+ -- Returns the drag coef of the ammo in a crate or gun
+ function ents_methods:acfDragCoef()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not ( isAmmo( this ) or isGun( this ) ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ return ( this.BulletData[ "DragCoef" ] or 0 ) / ACF.DragDiv
+ end
+
+ -- [ Armor Functions ] --
+
+ -- Returns the current health of an entity
+ function ents_methods:acfPropHealth ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not validPhysics( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not ACF_Check( this ) then return 0 end
+ return math.Round( this.ACF.Health or 0, 3 )
+ end
+
+ -- Returns the current armor of an entity
+ function ents_methods:acfPropArmor ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not validPhysics( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not ACF_Check( this ) then return 0 end
+ return math.Round( this.ACF.Armour or 0, 3 )
+ end
+
+ -- Returns the max health of an entity
+ function ents_methods:acfPropHealthMax ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not validPhysics( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not ACF_Check( this ) then return 0 end
+ return math.Round( this.ACF.MaxHealth or 0, 3 )
+ end
+
+ -- Returns the max armor of an entity
+ function ents_methods:acfPropArmorMax ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not validPhysics( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not ACF_Check( this ) then return 0 end
+ return math.Round( this.ACF.MaxArmour or 0, 3 )
+ end
+
+ -- Returns the ductility of an entity
+ function ents_methods:acfPropDuctility ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not validPhysics( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not ACF_Check( this ) then return 0 end
+ return ( this.ACF.Ductility or 0 ) * 100
+ end
+
+ -- [ Fuel Functions ] --
+
+ -- Returns true if the entity is an ACF fuel tank
+ function ents_methods:acfIsFuel ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isFuel( this ) and not restrictInfo( this ) then return true else return false end
+ end
+
+ -- Returns true if the current engine requires fuel to run
+ function ents_methods:acfFuelRequired ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return false end
+ if restrictInfo( this ) then return false end
+ return ( this.RequiresFuel and true ) or false
+ end
+
+ -- Sets the ACF fuel tank refuel duty status, which supplies fuel to other fuel tanks
+ function ents_methods:acfRefuelDuty ( on )
+ SF.CheckType( self, ents_metatable )
+ SF.CheckType( on, "boolean" )
+ local this = unwrap( self )
+
+ if not isFuel( this ) then return end
+ if restrictInfo( this ) then return end
+ this:TriggerInput( "Refuel Duty", on )
+ end
+
+ -- Returns the remaining liters or kilowatt hours of fuel in an ACF fuel tank or engine
+ function ents_methods:acfFuel ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isFuel( this ) then
+ if restrictInfo( this ) then return 0 end
+ return math.Round( this.Fuel, 3 )
+ elseif isEngine( this ) then
+ if restrictInfo( this ) then return 0 end
+ if not #(this.FuelLink) then return 0 end --if no tanks, return 0
+
+ local liters = 0
+ for _, tank in pairs( this.FuelLink ) do
+ if validPhysics( tank ) and tank.Active then
+ liters = liters + tank.Fuel
+ end
+ end
+
+ return math.Round( liters, 3 )
+ end
+ return 0
+ end
+
+ -- Returns the amount of fuel in an ACF fuel tank or linked to engine as a percentage of capacity
+ function ents_methods:acfFuelLevel ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if isFuel( this ) then
+ if restrictInfo( this ) then return 0 end
+ return math.Round( this.Fuel / this.Capacity, 3 )
+ elseif isEngine( this ) then
+ if restrictInfo( this ) then return 0 end
+ if not #( this.FuelLink ) then return 0 end --if no tanks, return 0
+
+ local liters = 0
+ local capacity = 0
+ for _, tank in pairs( this.FuelLink ) do
+ if validPhysics( tank ) and tank.Active then
+ capacity = capacity + tank.Capacity
+ liters = liters + tank.Fuel
+ end
+ end
+ if not capacity > 0 then return 0 end
+
+ return math.Round( liters / capacity, 3 )
+ end
+ return 0
+ end
+
+ -- Returns the current fuel consumption in liters per minute or kilowatts of an engine
+ function ents_methods:acfFuelUse ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not #( this.FuelLink ) then return 0 end --if no tanks, return 0
+
+ local tank
+ for _, fueltank in pairs( this.FuelLink ) do
+ if validPhysics( fueltank ) and fueltank.Fuel > 0 and fueltank.Active then
+ tank = fueltank
+ break
+ end
+ end
+ if not tank then return 0 end
+
+ local Consumption
+ if this.FuelType == "Electric" then
+ Consumption = 60 * ( this.Torque * this.FlyRPM / 9548.8 ) * this.FuelUse
+ else
+ local Load = 0.3 + this.Throttle * 0.7
+ Consumption = 60 * Load * this.FuelUse * ( this.FlyRPM / this.PeakKwRPM ) / ACF.FuelDensity[ tank.FuelType ]
+ end
+ return math.Round( Consumption, 3 )
+ end
+
+ -- Returns the peak fuel consumption in liters per minute or kilowatts of an engine at powerband max, for the current fuel type the engine is using
+ function ents_methods:acfPeakFuelUse ()
+ SF.CheckType( self, ents_metatable )
+ local this = unwrap( self )
+
+ if not isEngine( this ) then return 0 end
+ if restrictInfo( this ) then return 0 end
+ if not #( this.FuelLink ) then return 0 end --if no tanks, return 0
+
+ local fuel = "Petrol"
+ local tank
+ for _, fueltank in pairs( this.FuelLink ) do
+ if fueltank.Fuel > 0 and fueltank.Active then tank = fueltank break end
+ end
+ if tank then fuel = tank.Fuel end
+
+ local Consumption
+ if this.FuelType == "Electric" then
+ Consumption = 60 * ( this.PeakTorque * this.LimitRPM / ( 4 * 9548.8 ) ) * this.FuelUse
+ else
+ local Load = 0.3 + this.Throttle * 0.7
+ Consumption = 60 * this.FuelUse / ACF.FuelDensity[ fuel ]
+ end
+ return math.Round( Consumption, 3 )
+ end
+end)
\ No newline at end of file
diff --git a/lua/weapons/gmod_tool/stools/acfarmorprop.lua b/lua/weapons/gmod_tool/stools/acfarmorprop.lua
new file mode 100644
index 000000000..fd49d458e
--- /dev/null
+++ b/lua/weapons/gmod_tool/stools/acfarmorprop.lua
@@ -0,0 +1,299 @@
+
+local cat = ((ACF.CustomToolCategory and ACF.CustomToolCategory:GetBool()) and "ACF" or "Construction");
+
+TOOL.Category = cat
+TOOL.Name = "#tool.acfarmorprop.name"
+TOOL.Command = nil
+TOOL.ConfigName = ""
+
+TOOL.ClientConVar["thickness"] = 1
+TOOL.ClientConVar["ductility"] = 0
+CreateClientConVar( "acfarmorprop_area", 0, false, true ) -- we don't want this one to save
+
+-- Calculates mass, armor, and health given prop area and desired ductility and thickness.
+local function CalcArmor( Area, Ductility, Thickness )
+
+ local mass = Area * ( 1 + Ductility ) ^ 0.5 * Thickness * 0.00078
+ local armor = ACF_CalcArmor( Area, Ductility, mass )
+ local health = ( Area + Area * Ductility ) / ACF.Threshold
+
+ return mass, armor, health
+
+end
+
+if CLIENT then
+
+ language.Add( "tool.acfarmorprop.name", "ACF Armor Properties" )
+ language.Add( "tool.acfarmorprop.desc", "Sets the weight of a prop by desired armor thickness and ductility." )
+ language.Add( "tool.acfarmorprop.0", "Left click to apply settings. Right click to copy settings. Reload to get the total mass of an object and all constrained objects." )
+
+ function TOOL.BuildCPanel( panel )
+
+ local Presets = vgui.Create( "ControlPresets" )
+ Presets:AddConVar( "acfarmorprop_thickness" )
+ Presets:AddConVar( "acfarmorprop_ductility" )
+ Presets:SetPreset( "acfarmorprop" )
+ panel:AddItem( Presets )
+
+ panel:NumSlider( "Thickness", "acfarmorprop_thickness", 1, 5000 )
+ panel:ControlHelp( "Set the desired armor thickness (in mm) and the mass will be adjusted accordingly." )
+
+ panel:NumSlider( "Ductility", "acfarmorprop_ductility", -80, 80 )
+ panel:ControlHelp( "Set the desired armor ductility (thickness-vs-health bias). A ductile prop can survive more damage but is penetrated more easily (slider > 0). A non-ductile prop is brittle - hardened against penetration, but more easily shattered by bullets and explosions (slider < 0)." )
+
+ end
+
+ surface.CreateFont( "Torchfont", { size = 40, weight = 1000, font = "arial" } )
+
+ -- clamp thickness if the change in ductility puts mass out of range
+ cvars.AddChangeCallback( "acfarmorprop_ductility", function( cvar, oldvalue, value )
+
+ local area = GetConVarNumber( "acfarmorprop_area" )
+
+ -- don't bother recalculating if we don't have a valid ent
+ if area == 0 then return end
+
+ local ductility = math.Clamp( ( tonumber( value ) or 0 ) / 100, -0.8, 0.8 )
+ local thickness = math.Clamp( GetConVarNumber( "acfarmorprop_thickness" ), 0.1, 5000 )
+ local mass = CalcArmor( area, ductility, thickness )
+
+ if mass > 50000 then
+ mass = 50000
+ elseif mass < 0.1 then
+ mass = 0.1
+ else
+ return
+ end
+
+ thickness = mass * 1000 / ( area + area * ductility ) / 0.78
+ RunConsoleCommand( "acfarmorprop_thickness", thickness )
+
+ end )
+
+ -- clamp ductility if the change in thickness puts mass out of range
+ cvars.AddChangeCallback( "acfarmorprop_thickness", function( cvar, oldvalue, value )
+
+ local area = GetConVarNumber( "acfarmorprop_area" )
+
+ -- don't bother recalculating if we don't have a valid ent
+ if area == 0 then return end
+
+ local thickness = math.Clamp( tonumber( value ) or 0, 0.1, 5000 )
+ local ductility = math.Clamp( GetConVarNumber( "acfarmorprop_ductility" ) / 100, -0.8, 0.8 )
+ local mass = CalcArmor( area, ductility, thickness )
+
+ if mass > 50000 then
+ mass = 50000
+ elseif mass < 0.1 then
+ mass = 0.1
+ else
+ return
+ end
+
+ ductility = -( 39 * area * thickness - mass * 50000 ) / ( 39 * area * thickness )
+ RunConsoleCommand( "acfarmorprop_ductility", math.Clamp( ductility * 100, -80, 80 ) )
+
+ end )
+
+end
+
+-- Apply settings to prop and store dupe info
+local function ApplySettings( ply, ent, data )
+
+ if not SERVER then return end
+
+ if data.Mass then
+ local phys = ent:GetPhysicsObject()
+ if IsValid( phys ) then phys:SetMass( data.Mass ) end
+ duplicator.StoreEntityModifier( ent, "mass", { Mass = data.Mass } )
+ end
+
+ if data.Ductility then
+ ent.ACF = ent.ACF or {}
+ ent.ACF.Ductility = data.Ductility / 100
+ duplicator.StoreEntityModifier( ent, "acfsettings", { Ductility = data.Ductility } )
+ end
+
+end
+duplicator.RegisterEntityModifier( "acfsettings", ApplySettings )
+duplicator.RegisterEntityModifier( "mass", ApplySettings )
+
+-- Apply settings to prop
+function TOOL:LeftClick( trace )
+
+ local ent = trace.Entity
+
+ if not IsValid( ent ) or ent:IsPlayer() then return false end
+ if CLIENT then return true end
+ if not ACF_Check( ent ) then return false end
+
+ local ply = self:GetOwner()
+
+ local ductility = math.Clamp( self:GetClientNumber( "ductility" ), -80, 80 )
+ local thickness = math.Clamp( self:GetClientNumber( "thickness" ), 0.1, 50000 )
+ local mass = CalcArmor( ent.ACF.Aera, ductility / 100, thickness )
+
+ ApplySettings( ply, ent, { Mass = mass, Ductility = ductility } )
+
+ -- this invalidates the entity and forces a refresh of networked armor values
+ self.AimEntity = nil
+
+ return true
+
+end
+
+-- Suck settings from prop
+function TOOL:RightClick( trace )
+
+ local ent = trace.Entity
+
+ if not IsValid( ent ) or ent:IsPlayer() then return false end
+ if CLIENT then return true end
+ if not ACF_Check( ent ) then return false end
+
+ local ply = self:GetOwner()
+
+ ply:ConCommand( "acfarmorprop_ductility " .. ent.ACF.Ductility * 100 )
+ ply:ConCommand( "acfarmorprop_thickness " .. ent.ACF.MaxArmour )
+
+ -- this invalidates the entity and forces a refresh of networked armor values
+ self.AimEntity = nil
+
+ return true
+
+end
+
+-- Total up mass of constrained ents
+function TOOL:Reload( trace )
+
+ local ent = trace.Entity
+
+ if not IsValid( ent ) or ent:IsPlayer() then return false end
+ if CLIENT then return true end
+
+ local data = ACF_CalcMassRatio(ent, true)
+
+ local total = math.Round( ent.acftotal, 1 )
+ local phystotal = math.Round( ent.acfphystotal, 1 )
+ local parenttotal = math.Round( ent.acftotal - ent.acfphystotal, 1 )
+ local physratio = math.Round(100 * ent.acfphystotal / ent.acftotal, 1)
+
+ local pwr = "\n"
+ if data.Fuel == 2 then
+ pwr = pwr .. math.Round(data.Power * 1.25 / (ent.acftotal/1000), 1) .. " hp/ton @ " .. math.Round(data.Power * 1.25) .. " hp"
+ else
+ pwr = pwr .. math.Round(data.Power / (ent.acftotal/1000), 1) .. " hp/ton @ " .. math.Round(data.Power) .. " hp"
+ if data.Fuel == 1 then
+ pwr = pwr .. "\n" .. math.Round(data.Power * 1.25 / (ent.acftotal/1000), 1) .. " hp/ton @ " .. math.Round(data.Power * 1.25) .. " hp with fuel"
+ end
+ end
+
+ self:GetOwner():ChatPrint( "Total mass is " .. total .. " kg ("..phystotal.." kg physical, "..parenttotal.." kg parented, "..physratio.."% physical)"..pwr )
+
+end
+
+function TOOL:Think()
+
+ if not SERVER then return end
+
+ local ply = self:GetOwner()
+ local ent = ply:GetEyeTrace().Entity
+ if ent == self.AimEntity then return end
+
+ if ACF_Check( ent ) then
+
+ ply:ConCommand( "acfarmorprop_area " .. ent.ACF.Aera )
+ self.Weapon:SetNWFloat( "WeightMass", ent:GetPhysicsObject():GetMass() )
+ self.Weapon:SetNWFloat( "HP", ent.ACF.Health )
+ self.Weapon:SetNWFloat( "Armour", ent.ACF.Armour )
+ self.Weapon:SetNWFloat( "MaxHP", ent.ACF.MaxHealth )
+ self.Weapon:SetNWFloat( "MaxArmour", ent.ACF.MaxArmour )
+
+ else
+
+ ply:ConCommand( "acfarmorprop_area 0" )
+ self.Weapon:SetNWFloat( "WeightMass", 0 )
+ self.Weapon:SetNWFloat( "HP", 0 )
+ self.Weapon:SetNWFloat( "Armour", 0 )
+ self.Weapon:SetNWFloat( "MaxHP", 0 )
+ self.Weapon:SetNWFloat( "MaxArmour", 0 )
+
+ end
+
+ self.AimEntity = ent
+
+end
+
+function TOOL:DrawHUD()
+
+ if not CLIENT then return end
+
+ local ent = self:GetOwner():GetEyeTrace().Entity
+ if not IsValid( ent ) or ent:IsPlayer() then return end
+
+ local curmass = self.Weapon:GetNWFloat( "WeightMass" )
+ local curarmor = self.Weapon:GetNWFloat( "MaxArmour" )
+ local curhealth = self.Weapon:GetNWFloat( "MaxHP" )
+
+ local area = GetConVarNumber( "acfarmorprop_area" )
+ local ductility = GetConVarNumber( "acfarmorprop_ductility" )
+ local thickness = GetConVarNumber( "acfarmorprop_thickness" )
+
+ local mass, armor, health = CalcArmor( area, ductility / 100, thickness )
+ mass = math.min( mass, 50000 )
+
+ local text = "Current:\nMass: " .. math.Round( curmass, 2 )
+ text = text .. "\nArmor: " .. math.Round( curarmor, 2 )
+ text = text .. "\nHealth: " .. math.Round( curhealth, 2 )
+ text = text .. "\nAfter:\nMass: " .. math.Round( mass, 2 )
+ text = text .. "\nArmor: " .. math.Round( armor, 2 )
+ text = text .. "\nHealth: " .. math.Round( health, 2 )
+
+ local pos = ent:GetPos()
+ AddWorldTip( nil, text, nil, pos, nil )
+
+end
+
+function TOOL:DrawToolScreen( w, h )
+
+ if not CLIENT then return end
+
+ local Health = math.Round( self.Weapon:GetNWFloat( "HP", 0 ), 2 )
+ local MaxHealth = math.Round( self.Weapon:GetNWFloat( "MaxHP", 0 ), 2 )
+ local Armour = math.Round( self.Weapon:GetNWFloat( "Armour", 0 ), 2 )
+ local MaxArmour = math.Round( self.Weapon:GetNWFloat( "MaxArmour", 0 ), 2 )
+
+ local HealthTxt = Health .. "/" .. MaxHealth
+ local ArmourTxt = Armour .. "/" .. MaxArmour
+
+ cam.Start2D()
+ render.Clear( 0, 0, 0, 0 )
+
+ surface.SetMaterial( Material( "models/props_combine/combine_interface_disp" ) )
+ surface.SetDrawColor( color_white )
+ surface.DrawTexturedRect( 0, 0, 256, 256 )
+ surface.SetFont( "Torchfont" )
+
+ -- header
+ draw.SimpleTextOutlined( "ACF Stats", "Torchfont", 128, 30, Color( 224, 224, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, color_black )
+
+ -- armor bar
+ draw.RoundedBox( 6, 10, 83, 236, 64, Color( 200, 200, 200, 255 ) )
+ if Armour ~= 0 and MaxArmour ~= 0 then
+ draw.RoundedBox( 6, 15, 88, Armour / MaxArmour * 226, 54, Color( 0, 0, 200, 255 ) )
+ end
+
+ draw.SimpleTextOutlined( "Armour", "Torchfont", 128, 100, Color( 224, 224, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, color_black )
+ draw.SimpleTextOutlined( ArmourTxt, "Torchfont", 128, 130, Color( 224, 224, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, color_black )
+
+ -- health bar
+ draw.RoundedBox( 6, 10, 183, 236, 64, Color( 200, 200, 200, 255 ) )
+ if Health ~= 0 and MaxHealth ~= 0 then
+ draw.RoundedBox( 6, 15, 188, Health / MaxHealth * 226, 54, Color( 200, 0, 0, 255 ) )
+ end
+
+ draw.SimpleTextOutlined( "Health", "Torchfont", 128, 200, Color( 224, 224, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, color_black )
+ draw.SimpleTextOutlined( HealthTxt, "Torchfont", 128, 230, Color( 224, 224, 255, 255 ), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 4, color_black )
+ cam.End2D()
+
+end
diff --git a/lua/weapons/gmod_tool/stools/acfcopy.lua b/lua/weapons/gmod_tool/stools/acfcopy.lua
new file mode 100644
index 000000000..6895a8cdd
--- /dev/null
+++ b/lua/weapons/gmod_tool/stools/acfcopy.lua
@@ -0,0 +1,130 @@
+
+local cat = ((ACF.CustomToolCategory and ACF.CustomToolCategory:GetBool()) and "ACF" or "Construction");
+
+TOOL.Category = cat
+TOOL.Name = "#Tool.acfcopy.listname";
+TOOL.Author = "looter";
+TOOL.Command = nil;
+TOOL.ConfigName = "";
+
+TOOL.GearboxCopyData = {};
+TOOL.AmmoCopyData = {};
+
+if CLIENT then
+
+ language.Add( "Tool.acfcopy.listname", "ACF Copy Tool" );
+ language.Add( "Tool.acfcopy.name", "Armored Combat Framework" );
+ language.Add( "Tool.acfcopy.desc", "Copy ammo or gearbox data from one object to another" );
+ language.Add( "Tool.acfcopy.0", "Left click to paste data, Right click to copy data" );
+
+ function TOOL.BuildCPanel( CPanel )
+
+ end
+
+end
+
+-- Update
+function TOOL:LeftClick( trace )
+
+ if CLIENT then return end
+
+ local ent = trace.Entity;
+
+ if !IsValid( ent ) then
+ return false;
+ end
+
+ local pl = self:GetOwner();
+
+ if( ent:GetClass() == "acf_gearbox" and #self.GearboxCopyData > 1 and ent.CanUpdate ) then
+
+ local success, msg = ent:Update( self.GearboxCopyData );
+
+ ACF_SendNotify( pl, success, msg );
+
+ end
+
+ if( ent:GetClass() == "acf_ammo" and #self.AmmoCopyData > 1 and ent.CanUpdate ) then
+
+ local success, msg = ent:Update( self.AmmoCopyData );
+
+ ACF_SendNotify( pl, success, msg );
+
+ end
+
+ return true;
+
+end
+
+-- Copy
+function TOOL:RightClick( trace )
+
+ if CLIENT then return end
+
+ local ent = trace.Entity;
+
+ if !IsValid( ent ) then
+ return false;
+ end
+
+ local pl = self:GetOwner();
+
+ if( ent:GetClass() == "acf_gearbox" ) then
+
+ local ArgsTable = {};
+
+ -- zero out the un-needed tool trace information
+ ArgsTable[1] = pl;
+ ArgsTable[2] = 0;
+ ArgsTable[3] = 0;
+ ArgsTable[4] = ent.Id;
+
+ -- build gear data
+ ArgsTable[5] = ent.GearTable[1];
+ ArgsTable[6] = ent.GearTable[2];
+ ArgsTable[7] = ent.GearTable[3];
+ ArgsTable[8] = ent.GearTable[4];
+ ArgsTable[9] = ent.GearTable[5];
+ ArgsTable[10] = ent.GearTable[6];
+ ArgsTable[11] = ent.GearTable[7];
+ ArgsTable[12] = ent.GearTable[8];
+ ArgsTable[13] = ent.GearTable[9];
+ ArgsTable[14] = ent.GearTable.Final;
+
+ self.GearboxCopyData = ArgsTable;
+
+ ACF_SendNotify( pl, true, "Gearbox copied successfully!" );
+
+ end
+
+ if( ent:GetClass() == "acf_ammo" ) then
+
+ local ArgsTable = {};
+
+ -- zero out the un-needed tool trace information
+ ArgsTable[1] = pl;
+ ArgsTable[2] = 0;
+ ArgsTable[3] = 0;
+ ArgsTable[4] = 0; -- ArgsTable[4] isnt actually used anywhere within acf_ammo ENT:Update() and ENT:CreateAmmo(), just passed around?
+
+ -- build gear data
+ ArgsTable[5] = ent.RoundId;
+ ArgsTable[6] = ent.RoundType;
+ ArgsTable[7] = ent.RoundPropellant;
+ ArgsTable[8] = ent.RoundProjectile;
+ ArgsTable[9] = ent.RoundData5;
+ ArgsTable[10] = ent.RoundData6;
+ ArgsTable[11] = ent.RoundData7;
+ ArgsTable[12] = ent.RoundData8;
+ ArgsTable[13] = ent.RoundData9;
+ ArgsTable[14] = ent.RoundData10;
+
+ self.AmmoCopyData = ArgsTable;
+
+ ACF_SendNotify( pl, true, "Ammo copied successfully!" );
+
+ end
+
+ return true;
+
+end
diff --git a/lua/weapons/gmod_tool/stools/acfmenu.lua b/lua/weapons/gmod_tool/stools/acfmenu.lua
index 4a69b82d2..e8d4f7d89 100644
--- a/lua/weapons/gmod_tool/stools/acfmenu.lua
+++ b/lua/weapons/gmod_tool/stools/acfmenu.lua
@@ -1,5 +1,8 @@
-TOOL.Category = "Construction"
-TOOL.Name = "#ACFMenu"
+
+local cat = ((ACF.CustomToolCategory and ACF.CustomToolCategory:GetBool()) and "ACF" or "Construction");
+
+TOOL.Category = cat
+TOOL.Name = "#Tool.acfmenu.listname"
TOOL.Command = nil
TOOL.ConfigName = ""
@@ -19,13 +22,18 @@ TOOL.ClientConVar[ "data10" ] = 0
cleanup.Register( "acfmenu" )
-if CLIENT then
+if CLIENT then
+ language.Add( "Tool.acfmenu.listname", "ACF Menu" )
language.Add( "Tool.acfmenu.name", "Armored Combat Framework" )
language.Add( "Tool.acfmenu.desc", "Spawn the Armored Combat Framework weapons and ammo" )
language.Add( "Tool.acfmenu.0", "Left click to spawn the entity of your choice, Right click to link an entity to another (+Use to unlink)" )
language.Add( "Tool.acfmenu.1", "Right click to link the selected sensor to a pod" )
language.Add( "Undone_ACF Entity", "Undone ACF Entity" )
+ language.Add( "Undone_acf_engine", "Undone ACF Engine" )
+ language.Add( "Undone_acf_gearbox", "Undone ACF Gearbox" )
+ language.Add( "Undone_acf_ammo", "Undone ACF Ammo" )
+ language.Add( "Undone_acf_gun", "Undone ACF Gun" )
language.Add( "SBoxLimit_acf_gun", "You've reached the ACF Guns limit!" )
language.Add( "SBoxLimit_acf_rack", "You've reached the ACF Launchers limit!" )
language.Add( "SBoxLimit_acf_ammo", "You've reached the ACF Explosives limit!" )
@@ -43,45 +51,52 @@ if CLIENT then
CPanel:AddPanel( DPanel )
end
-
-else
-
-
end
+-- Spawn/update functions
function TOOL:LeftClick( trace )
- if (CLIENT) then return true end
-
- if ( !trace.Entity:IsValid() && !trace.Entity:IsWorld() ) then return false end
+ if CLIENT then return true end
+ if not IsValid( trace.Entity ) and not trace.Entity:IsWorld() then return false end
local ply = self:GetOwner()
local Type = self:GetClientInfo( "type" )
local Id = self:GetClientInfo( "id" )
- local SpawnPos = trace.HitPos
- local DupeClass = duplicator.FindEntityClass( ACF.Weapons[Type][Id]["ent"] )
- if ( DupeClass ) then
+ local TypeId = ACF.Weapons[Type][Id]
+ if not TypeId then return false end
+
+ local DupeClass = duplicator.FindEntityClass( TypeId["ent"] )
+
+ if DupeClass then
local ArgTable = {}
ArgTable[2] = trace.HitNormal:Angle():Up():Angle()
ArgTable[1] = trace.HitPos + trace.HitNormal*32
+
local ArgList = list.Get("ACFCvars")
- for Number, Key in pairs( ArgList[ACF.Weapons[Type][Id]["ent"]] ) do --Reading the list packaged with the ent to see what client CVar it needs
+
+ -- Reading the list packaged with the ent to see what client CVar it needs
+ for Number, Key in pairs( ArgList[ACF.Weapons[Type][Id]["ent"]] ) do
ArgTable[ Number+2 ] = self:GetClientInfo( Key )
end
- local Feedback = nil
- if ( trace.Entity:GetClass() == ACF.Weapons[Type][Id]["ent"] and trace.Entity.CanUpdate ) then
- table.insert(ArgTable,1,ply)
- Feedback = trace.Entity:Update( ArgTable )
+ if trace.Entity:GetClass() == ACF.Weapons[Type][Id]["ent"] and trace.Entity.CanUpdate then
+ table.insert( ArgTable, 1, ply )
+ local success, msg = trace.Entity:Update( ArgTable )
+ ACF_SendNotify( ply, success, msg )
else
- local Ent = DupeClass.Func(ply, unpack(ArgTable)) --Using the Duplicator entity register to find the right factory function
+ -- Using the Duplicator entity register to find the right factory function
+ local Ent = DupeClass.Func( ply, unpack( ArgTable ) )
+ if not IsValid(Ent) then ACF_SendNotify(ply, false, "Couldn't create entity.") return false end
Ent:Activate()
- Ent:GetPhysicsObject():Wake()
- end
-
- if Feedback != nil then
- self:GetOwner():SendLua( string.format( "GAMEMODE:AddNotify(%q,%s,7)", Feedback, "NOTIFY_ERROR" ) )
+ --Ent:GetPhysicsObject():Wake()
+ Ent:DropToFloor()
+ Ent:GetPhysicsObject():EnableMotion( false )
+
+ undo.Create( ACF.Weapons[Type][Id]["ent"] )
+ undo.AddEntity( Ent )
+ undo.SetPlayer( ply )
+ undo.Finish()
end
return true
@@ -91,69 +106,34 @@ function TOOL:LeftClick( trace )
end
+-- Link/unlink functions
function TOOL:RightClick( trace )
- if !trace.Entity || !trace.Entity:IsValid() then
- return false end
-
- if (CLIENT) then return true end
+ if not IsValid( trace.Entity ) then return false end
+ if CLIENT then return true end
- if self:GetOwner():KeyDown( IN_USE ) then
+ local ply = self:GetOwner()
- if (self:GetStage() == 0) and trace.Entity.IsMaster then
- self.Master = trace.Entity
- self:SetStage(1)
- return true
- elseif self:GetStage() == 1 then
- local Error = self.Master:Unlink( trace.Entity )
- if !Error then
- self:GetOwner():SendLua( "GAMEMODE:AddNotify('Unlink Succesful', NOTIFY_GENERIC, 7);" )
- elseif Error != nil then
- self:GetOwner():SendLua( string.format( "GAMEMODE:AddNotify(%q,%s,7)", Error, "NOTIFY_ERROR" ) )
- else
- self:GetOwner():SendLua( "GAMEMODE:AddNotify('Unlink Failed', NOTIFY_GENERIC, 7);" )
- end
- self:SetStage(0)
- self.Master = nil
- return true
+ if self:GetStage() == 0 and trace.Entity.IsMaster then
+ self.Master = trace.Entity
+ self:SetStage( 1 )
+ return true
+ elseif self:GetStage() == 1 then
+ local success, msg
+
+ if ply:KeyDown( IN_USE ) or ply:KeyDown( IN_SPEED ) then
+ success, msg = self.Master:Unlink( trace.Entity )
else
- return false
+ success, msg = self.Master:Link( trace.Entity )
end
+ ACF_SendNotify( ply, success, msg )
+
+ self:SetStage( 0 )
+ self.Master = nil
+ return true
else
-
- if (self:GetStage() == 0) and trace.Entity.IsMaster then
- self.Master = trace.Entity
- self:SetStage(1)
- return true
- elseif self:GetStage() == 1 then
- local Error = self.Master:Link( trace.Entity )
- if !Error then
- self:GetOwner():SendLua( "GAMEMODE:AddNotify('Link Succesful', NOTIFY_GENERIC, 7);" )
- elseif Error != nil then
- self:GetOwner():SendLua( string.format( "GAMEMODE:AddNotify(%q,%s,7)", Error, "NOTIFY_ERROR" ) )
- else
- self:GetOwner():SendLua( "GAMEMODE:AddNotify('Link Failed', NOTIFY_GENERIC, 7);" )
- end
- self:SetStage(0)
- self.Master = nil
- return true
- else
- return false
- end
-
+ return false
end
end
-
-function TOOL:Reload( trace )
-
-
-end
-
-function TOOL:Think()
-
-
-end
-
-
diff --git a/lua/weapons/gmod_tool/stools/acfsound.lua b/lua/weapons/gmod_tool/stools/acfsound.lua
new file mode 100644
index 000000000..f1d1e6da9
--- /dev/null
+++ b/lua/weapons/gmod_tool/stools/acfsound.lua
@@ -0,0 +1,243 @@
+
+local cat = ((ACF.CustomToolCategory and ACF.CustomToolCategory:GetBool()) and "ACF" or "Construction");
+
+TOOL.Category = cat
+TOOL.Name = "#Tool.acfsound.name"
+TOOL.Command = nil
+TOOL.ConfigName = ""
+
+TOOL.ClientConVar["pitch"] = "1"
+if CLIENT then
+ language.Add( "Tool.acfsound.name", "ACF Sound Replacer" )
+ language.Add( "Tool.acfsound.desc", "Change sound of guns/engines." )
+ language.Add( "Tool.acfsound.0", "Left click to apply sound. Right click to copy sound. Reload to set default sound. Use an empty sound path to disable sound." )
+end
+
+
+
+
+ACF.SoundToolSupport =
+{
+ acf_gun =
+ {
+ GetSound = function(ent) return {Sound = ent.Sound} end,
+
+ SetSound = function(ent, soundData)
+ ent.Sound = soundData.Sound
+ ent:SetNWString( "Sound", soundData.Sound )
+ end,
+
+ ResetSound = function(ent)
+ local Class = ent.Class
+ local Classes = list.Get("ACFClasses")
+
+ local soundData = {Sound = Classes["GunClass"][Class]["sound"]}
+
+ local setSound = ACF.SoundToolSupport["acf_gun"].SetSound
+ setSound( ent, soundData )
+ end
+ },
+
+ acf_engine =
+ {
+ GetSound = function(ent) return {Sound = ent.SoundPath, Pitch = ent.SoundPitch} end,
+
+ SetSound = function(ent, soundData)
+ ent.SoundPath = soundData.Sound
+ ent.SoundPitch = soundData.Pitch
+ end,
+
+ ResetSound = function(ent)
+ local Id = ent.Id
+ local List = list.Get("ACFEnts")
+ local pitch = List["Mobility"][Id]["pitch"] or 1
+
+ local soundData = {Sound = List["Mobility"][Id]["sound"], Pitch = pitch}
+
+ local setSound = ACF.SoundToolSupport["acf_engine"].SetSound
+ setSound( ent, soundData )
+ end
+ },
+}
+
+
+
+
+local function ReplaceSound( ply , Entity , data)
+ if !IsValid( Entity ) then return end
+ local sound = data[1]
+ local pitch = data[2] or 1
+
+ timer.Simple(1, function()
+ local class = Entity:GetClass()
+
+ local support = ACF.SoundToolSupport[class]
+ if not support then return end
+
+ support.SetSound(Entity, {Sound = sound, Pitch = pitch})
+ end)
+
+ duplicator.StoreEntityModifier( Entity, "acf_replacesound", {sound, pitch} )
+end
+
+duplicator.RegisterEntityModifier( "acf_replacesound", ReplaceSound )
+
+
+
+
+local function IsReallyValid(trace, ply)
+
+ local isValid = true
+
+ if not trace.Entity:IsValid() then return false end
+ if trace.Entity:IsPlayer() then return false end
+ if SERVER and not trace.Entity:GetPhysicsObject():IsValid() then return false end
+
+
+ local class = trace.Entity:GetClass()
+ if not ACF.SoundToolSupport[class] then
+
+ if string.StartWith(class, "acf_") then
+ ACF_SendNotify( ply, false, class .. " is not supported by the sound tool!" )
+ else
+ ACF_SendNotify( ply, false, "Only ACF entities are supported by the ACF sound tool!" )
+ end
+
+ return false
+ end
+
+ return true
+
+end
+
+
+
+
+function TOOL:LeftClick( trace )
+ if CLIENT then return true end
+ if not IsReallyValid( trace, self:GetOwner() ) then return false end
+
+ local sound = self:GetOwner():GetInfo("wire_soundemitter_sound")
+ local pitch = self:GetOwner():GetInfo("acfsound_pitch")
+ ReplaceSound( self:GetOwner(), trace.Entity, {sound, pitch} )
+ return true
+end
+
+
+
+
+function TOOL:RightClick( trace )
+ if CLIENT then return true end
+ if not IsReallyValid( trace, self:GetOwner() ) then return false end
+
+ local class = trace.Entity:GetClass()
+ local support = ACF.SoundToolSupport[class]
+ if not support then return false end
+
+ local soundData = support.GetSound(trace.Entity)
+
+ self:GetOwner():ConCommand("wire_soundemitter_sound "..soundData.Sound);
+
+ if soundData.Pitch then
+ self:GetOwner():ConCommand("acfsound_pitch "..soundData.Pitch);
+ end
+
+ return true
+end
+
+
+
+
+function TOOL:Reload( trace )
+ if CLIENT then return true end
+ if not IsReallyValid( trace, self:GetOwner() ) then return false end
+
+ local class = trace.Entity:GetClass()
+ local support = ACF.SoundToolSupport[class]
+ if not support then return false end
+
+ support.ResetSound(trace.Entity)
+
+ return true
+end
+
+
+
+
+function TOOL.BuildCPanel(panel)
+ local wide = panel:GetWide()
+
+ local SoundNameText = vgui.Create("DTextEntry", ValuePanel)
+ SoundNameText:SetText("")
+ SoundNameText:SetWide(wide)
+ SoundNameText:SetTall(20)
+ SoundNameText:SetMultiline(false)
+ SoundNameText:SetConVar("wire_soundemitter_sound")
+ SoundNameText:SetVisible(true)
+ panel:AddItem(SoundNameText)
+
+ local SoundBrowserButton = vgui.Create("DButton")
+ SoundBrowserButton:SetText("Open Sound Browser")
+ SoundBrowserButton:SetWide(wide)
+ SoundBrowserButton:SetTall(20)
+ SoundBrowserButton:SetVisible(true)
+ SoundBrowserButton.DoClick = function()
+ RunConsoleCommand("wire_sound_browser_open",SoundNameText:GetValue())
+ end
+ panel:AddItem(SoundBrowserButton)
+
+ local SoundPre = vgui.Create("DPanel")
+ SoundPre:SetWide(wide)
+ SoundPre:SetTall(20)
+ SoundPre:SetVisible(true)
+
+ local SoundPreWide = SoundPre:GetWide()
+
+ local SoundPrePlay = vgui.Create("DButton", SoundPre)
+ SoundPrePlay:SetText("Play")
+ SoundPrePlay:SetWide(SoundPreWide / 2)
+ SoundPrePlay:SetPos(0, 0)
+ SoundPrePlay:SetTall(20)
+ SoundPrePlay:SetVisible(true)
+ SoundPrePlay.DoClick = function()
+ RunConsoleCommand("play",SoundNameText:GetValue())
+ end
+
+ local SoundPreStop = vgui.Create("DButton", SoundPre)
+ SoundPreStop:SetText("Stop")
+ SoundPreStop:SetWide(SoundPreWide / 2)
+ SoundPreStop:SetPos(SoundPreWide / 2, 0)
+ SoundPreStop:SetTall(20)
+ SoundPreStop:SetVisible(true)
+ SoundPreStop.DoClick = function()
+ RunConsoleCommand("play", "common/NULL.WAV") //Playing a silent sound will mute the preview but not the sound emitters.
+ end
+ panel:AddItem(SoundPre)
+ SoundPre:InvalidateLayout(true)
+ SoundPre.PerformLayout = function()
+ local SoundPreWide = SoundPre:GetWide()
+ SoundPrePlay:SetWide(SoundPreWide / 2)
+ SoundPreStop:SetWide(SoundPreWide / 2)
+ SoundPreStop:SetPos(SoundPreWide / 2, 0)
+ end
+
+ panel:AddControl("Slider", {
+ Label = "Pitch:",
+ Command = "acfsound_pitch",
+ Type = "Float",
+ Min = "0.1",
+ Max = "2",
+ }):SetTooltip("Works only for engines.")
+ /*
+ local SoundPitch = vgui.Create("DNumSlider")
+ SoundPitch:SetMin( 0.1 )
+ SoundPitch:SetMax( 2 )
+ SoundPitch:SetDecimals( 0.1 )
+ SoundPitch:SetWide(wide)
+ SoundPitch:SetText("Pitch:")
+ SoundPitch:SetToolTip("Works only for engines")
+ SoundPitch:SetConVar( "acfsound_pitch" )
+ SoundPitch:SetValue( 1 )
+ panel:AddItem(SoundPitch)
+ */
+end
diff --git a/lua/weapons/torch/cl_init.lua b/lua/weapons/torch/cl_init.lua
index 3e2561efc..540bd15e4 100644
--- a/lua/weapons/torch/cl_init.lua
+++ b/lua/weapons/torch/cl_init.lua
@@ -10,10 +10,10 @@ local tex = surface.GetTextureID( "models/props_combine/combine_interface_disp"
function SWEP:ViewModelDrawn()
- local Health = math.floor((self.Weapon:GetNetworkedBool("HP")or 0) *10)/10
- local MaxHealth = math.floor((self.Weapon:GetNetworkedBool("MaxHP")or 0) * 10)/10
- local Armour = math.floor((self.Weapon:GetNetworkedBool("Armour")or 0) *100)/100
- local MaxArmour = math.floor((self.Weapon:GetNetworkedBool("MaxArmour")or 0) *100)/100
+ local Health = math.floor(self.Weapon:GetNWFloat("HP", 0) *10)/10
+ local MaxHealth = math.floor(self.Weapon:GetNWFloat("MaxHP", 0) * 10)/10
+ local Armour = math.floor(self.Weapon:GetNWFloat("Armour", 0) *100)/100
+ local MaxArmour = math.floor(self.Weapon:GetNWFloat("MaxArmour", 0) *100)/100
local HealthTxt = Health.."/"..MaxHealth.."\n"
local ArmourTxt = Armour.."/"..MaxArmour.."\n"
diff --git a/lua/weapons/torch/shared.lua b/lua/weapons/torch/shared.lua
index d17ca06db..acdce85d1 100644
--- a/lua/weapons/torch/shared.lua
+++ b/lua/weapons/torch/shared.lua
@@ -69,10 +69,10 @@ function SWEP:Think()
self.LastSend = CurTime() + 1
local Valid = ACF_Check( ent )
if Valid then
- self.Weapon:SetNetworkedInt( "HP", ent.ACF.Health )
- self.Weapon:SetNetworkedInt( "Armour", ent.ACF.Armour )
- self.Weapon:SetNetworkedInt( "MaxHP", ent.ACF.MaxHealth )
- self.Weapon:SetNetworkedInt( "MaxArmour", ent.ACF.MaxArmour )
+ self.Weapon:SetNWFloat( "HP", ent.ACF.Health )
+ self.Weapon:SetNWFloat( "Armour", ent.ACF.Armour )
+ self.Weapon:SetNWFloat( "MaxHP", ent.ACF.MaxHealth )
+ self.Weapon:SetNWFloat( "MaxArmour", ent.ACF.MaxArmour )
end
end
end
@@ -106,10 +106,10 @@ function SWEP:PrimaryAttack()
PlayerHealth = PlayerHealth + 1 --otherwise add 1 HP
ent:SetHealth( PlayerHealth ) --and boost the player's HP to that.
- self.Weapon:SetNetworkedInt( "HP", PlayerHealth ) --Output to the HUD bar
- self.Weapon:SetNetworkedInt( "Armour", PlayerArmour )
- self.Weapon:SetNetworkedInt( "MaxHP", PlayerMaxHealth )
- self.Weapon:SetNetworkedInt( "MaxArmour", PlayerMaxArmour )
+ self.Weapon:SetNWFloat( "HP", PlayerHealth ) --Output to the HUD bar
+ self.Weapon:SetNWFloat( "Armour", PlayerArmour )
+ self.Weapon:SetNWFloat( "MaxHP", PlayerMaxHealth )
+ self.Weapon:SetNWFloat( "MaxArmour", PlayerMaxArmour )
local effect = EffectData()--then make some pretty effects :D ("Fixed that up a bit so it looks like it's actually emanating from the healing player, well mostly" Kaf)
local AngPos = userid:GetAttachment( 4 )
@@ -119,6 +119,7 @@ function SWEP:PrimaryAttack()
util.Effect( "thruster_ring", effect, true, true ) --("The 2 booleans control clientside override, by default it doesn't display it since it'll lag a bit behind inputs in MP, same for sounds" Kaf)
ent:EmitSound( "items/medshot4.wav", true, true )--and play a sound.
else
+ if CPPI and not ent:CPPICanTool( self.Owner, "torch" ) then return false end
local Valid = ACF_Check ( ent )
if ( Valid and ent.ACF.Health < ent.ACF.MaxHealth ) then
ent.ACF.Health = math.min(ent.ACF.Health + (30/ent.ACF.MaxArmour),ent.ACF.MaxHealth)
@@ -126,16 +127,16 @@ function SWEP:PrimaryAttack()
ent:EmitSound( "ambient/energy/NewSpark0" ..tostring( math.random( 3, 5 ) ).. ".wav", true, true )--Welding noise here, gotte figure out how to do a looped sound.
TeslaSpark(tr.HitPos , 1 )
end
- self.Weapon:SetNetworkedInt( "HP", ent.ACF.Health )
- self.Weapon:SetNetworkedInt( "Armour", ent.ACF.Armour )
- self.Weapon:SetNetworkedInt( "MaxHP", ent.ACF.MaxHealth )
- self.Weapon:SetNetworkedInt( "MaxArmour", ent.ACF.MaxArmour )
+ self.Weapon:SetNWFloat( "HP", ent.ACF.Health )
+ self.Weapon:SetNWFloat( "Armour", ent.ACF.Armour )
+ self.Weapon:SetNWFloat( "MaxHP", ent.ACF.MaxHealth )
+ self.Weapon:SetNWFloat( "MaxArmour", ent.ACF.MaxArmour )
end
else
- self.Weapon:SetNetworkedInt( "HP", 0 )
- self.Weapon:SetNetworkedInt( "Armour", 0 )
- self.Weapon:SetNetworkedInt( "MaxHP", 0 )
- self.Weapon:SetNetworkedInt( "MaxArmour", 0 )
+ self.Weapon:SetNWFloat( "HP", 0 )
+ self.Weapon:SetNWFloat( "Armour", 0 )
+ self.Weapon:SetNWFloat( "MaxHP", 0 )
+ self.Weapon:SetNWFloat( "MaxArmour", 0 )
end
end
@@ -156,14 +157,15 @@ self.Weapon:SetNextPrimaryFire( CurTime() + 0.05 )
if ent:IsValid() then
local Valid = ACF_Check ( ent )
if Valid then
- self.Weapon:SetNetworkedInt( "HP", ent.ACF.Health )
- self.Weapon:SetNetworkedInt( "Armour", ent.ACF.Armour )
- self.Weapon:SetNetworkedInt( "MaxHP", ent.ACF.MaxHealth )
- self.Weapon:SetNetworkedInt( "MaxArmour", ent.ACF.MaxArmour )
+ self.Weapon:SetNWFloat( "HP", ent.ACF.Health )
+ self.Weapon:SetNWFloat( "Armour", ent.ACF.Armour )
+ self.Weapon:SetNWFloat( "MaxHP", ent.ACF.MaxHealth )
+ self.Weapon:SetNWFloat( "MaxArmour", ent.ACF.MaxArmour )
local HitRes = {}
if(ent:IsPlayer()) then
HitRes = ACF_Damage ( ent , {Kinetic = 0.05,Momentum = 0,Penetration = 0.05} , 2 , 0 , self.Owner )--We can use the damage function instead of direct access here since no numbers are negative.
else
+ if CPPI and not ent:CPPICanTool( self.Owner, "torch" ) then return false end
HitRes = ACF_Damage ( ent , {Kinetic = 5,Momentum = 0,Penetration = 5} , 2 , 0 , self.Owner )--We can use the damage function instead of direct access here since no numbers are negative.
end
if HitRes.Kill then
@@ -184,10 +186,10 @@ self.Weapon:SetNextPrimaryFire( CurTime() + 0.05 )
ent:EmitSound( "weapons/physcannon/superphys_small_zap" ..tostring( math.random( 1, 4 ) ).. ".wav", true , true ) --old annoyinly loud sounds
end
else
- self.Weapon:SetNetworkedInt( "HP", 0 )
- self.Weapon:SetNetworkedInt( "Armour", 0 )
- self.Weapon:SetNetworkedInt( "MaxHP", 0 )
- self.Weapon:SetNetworkedInt( "MaxArmour", 0 )
+ self.Weapon:SetNWFloat( "HP", 0 )
+ self.Weapon:SetNWFloat( "Armour", 0 )
+ self.Weapon:SetNWFloat( "MaxHP", 0 )
+ self.Weapon:SetNWFloat( "MaxArmour", 0 )
end
end
diff --git a/materials/HUD/killicons/acf_AC.vmt b/materials/HUD/killicons/acf_AC.vmt
new file mode 100644
index 000000000..2c43eda77
--- /dev/null
+++ b/materials/HUD/killicons/acf_AC.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_AC"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_AC.vtf b/materials/HUD/killicons/acf_AC.vtf
new file mode 100644
index 000000000..0e2db3883
Binary files /dev/null and b/materials/HUD/killicons/acf_AC.vtf differ
diff --git a/materials/HUD/killicons/acf_AL.vmt b/materials/HUD/killicons/acf_AL.vmt
new file mode 100644
index 000000000..f59734a68
--- /dev/null
+++ b/materials/HUD/killicons/acf_AL.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_AL"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_AL.vtf b/materials/HUD/killicons/acf_AL.vtf
new file mode 100644
index 000000000..88c189bf6
Binary files /dev/null and b/materials/HUD/killicons/acf_AL.vtf differ
diff --git a/materials/HUD/killicons/acf_C.vmt b/materials/HUD/killicons/acf_C.vmt
new file mode 100644
index 000000000..f8a03492c
--- /dev/null
+++ b/materials/HUD/killicons/acf_C.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_C"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_C.vtf b/materials/HUD/killicons/acf_C.vtf
new file mode 100644
index 000000000..f0a10e13c
Binary files /dev/null and b/materials/HUD/killicons/acf_C.vtf differ
diff --git a/materials/HUD/killicons/acf_GL.vmt b/materials/HUD/killicons/acf_GL.vmt
new file mode 100644
index 000000000..a8369e2d8
--- /dev/null
+++ b/materials/HUD/killicons/acf_GL.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_GL"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_GL.vtf b/materials/HUD/killicons/acf_GL.vtf
new file mode 100644
index 000000000..3a46b684b
Binary files /dev/null and b/materials/HUD/killicons/acf_GL.vtf differ
diff --git a/materials/HUD/killicons/acf_HMG.vmt b/materials/HUD/killicons/acf_HMG.vmt
new file mode 100644
index 000000000..0c049c5da
--- /dev/null
+++ b/materials/HUD/killicons/acf_HMG.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_HMG"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_HMG.vtf b/materials/HUD/killicons/acf_HMG.vtf
new file mode 100644
index 000000000..557d12961
Binary files /dev/null and b/materials/HUD/killicons/acf_HMG.vtf differ
diff --git a/materials/HUD/killicons/acf_HW.vmt b/materials/HUD/killicons/acf_HW.vmt
new file mode 100644
index 000000000..55dc91ee3
--- /dev/null
+++ b/materials/HUD/killicons/acf_HW.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_HW"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_HW.vtf b/materials/HUD/killicons/acf_HW.vtf
new file mode 100644
index 000000000..cbe8c8af1
Binary files /dev/null and b/materials/HUD/killicons/acf_HW.vtf differ
diff --git a/materials/HUD/killicons/acf_MG.vmt b/materials/HUD/killicons/acf_MG.vmt
new file mode 100644
index 000000000..80d850eca
--- /dev/null
+++ b/materials/HUD/killicons/acf_MG.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_MG"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_MG.vtf b/materials/HUD/killicons/acf_MG.vtf
new file mode 100644
index 000000000..6244f248f
Binary files /dev/null and b/materials/HUD/killicons/acf_MG.vtf differ
diff --git a/materials/HUD/killicons/acf_MO.vmt b/materials/HUD/killicons/acf_MO.vmt
new file mode 100644
index 000000000..bccb8540b
--- /dev/null
+++ b/materials/HUD/killicons/acf_MO.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_MO"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_MO.vtf b/materials/HUD/killicons/acf_MO.vtf
new file mode 100644
index 000000000..d2320cd2c
Binary files /dev/null and b/materials/HUD/killicons/acf_MO.vtf differ
diff --git a/materials/HUD/killicons/acf_RAC.vmt b/materials/HUD/killicons/acf_RAC.vmt
new file mode 100644
index 000000000..4050891ac
--- /dev/null
+++ b/materials/HUD/killicons/acf_RAC.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_RAC"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_RAC.vtf b/materials/HUD/killicons/acf_RAC.vtf
new file mode 100644
index 000000000..00b5c4366
Binary files /dev/null and b/materials/HUD/killicons/acf_RAC.vtf differ
diff --git a/materials/HUD/killicons/acf_SA.vmt b/materials/HUD/killicons/acf_SA.vmt
new file mode 100644
index 000000000..a90fa2e97
--- /dev/null
+++ b/materials/HUD/killicons/acf_SA.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_SA"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_SA.vtf b/materials/HUD/killicons/acf_SA.vtf
new file mode 100644
index 000000000..78d21be87
Binary files /dev/null and b/materials/HUD/killicons/acf_SA.vtf differ
diff --git a/materials/HUD/killicons/acf_ammo.vmt b/materials/HUD/killicons/acf_ammo.vmt
new file mode 100644
index 000000000..18a9fac7f
--- /dev/null
+++ b/materials/HUD/killicons/acf_ammo.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_ammo"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_ammo.vtf b/materials/HUD/killicons/acf_ammo.vtf
new file mode 100644
index 000000000..0e955f29a
Binary files /dev/null and b/materials/HUD/killicons/acf_ammo.vtf differ
diff --git a/materials/HUD/killicons/acf_gun.vmt b/materials/HUD/killicons/acf_gun.vmt
new file mode 100644
index 000000000..396eb9ffb
--- /dev/null
+++ b/materials/HUD/killicons/acf_gun.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/acf_gun"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/acf_gun.vtf b/materials/HUD/killicons/acf_gun.vtf
new file mode 100644
index 000000000..95e9db829
Binary files /dev/null and b/materials/HUD/killicons/acf_gun.vtf differ
diff --git a/materials/HUD/killicons/torch.vmt b/materials/HUD/killicons/torch.vmt
new file mode 100644
index 000000000..3e11d114f
--- /dev/null
+++ b/materials/HUD/killicons/torch.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$basetexture" "HUD/killicons/torch"
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+ "$nolod" 1
+ "$additive" 1 // hldm style!
+}
diff --git a/materials/HUD/killicons/torch.vtf b/materials/HUD/killicons/torch.vtf
new file mode 100644
index 000000000..aab611cda
Binary files /dev/null and b/materials/HUD/killicons/torch.vtf differ
diff --git a/materials/damaged/damaged1.vmt b/materials/damaged/damaged1.vmt
new file mode 100644
index 000000000..15d2a89da
--- /dev/null
+++ b/materials/damaged/damaged1.vmt
@@ -0,0 +1,5 @@
+"LightmappedGeneric"
+{
+ "$basetexture" "damaged/damaged1"
+ "$model" "1"
+}
diff --git a/materials/damaged/damaged1.vtf b/materials/damaged/damaged1.vtf
new file mode 100644
index 000000000..d3456d3b0
Binary files /dev/null and b/materials/damaged/damaged1.vtf differ
diff --git a/materials/damaged/damaged2.vmt b/materials/damaged/damaged2.vmt
new file mode 100644
index 000000000..359ae5cd7
--- /dev/null
+++ b/materials/damaged/damaged2.vmt
@@ -0,0 +1,5 @@
+"LightmappedGeneric"
+{
+ "$basetexture" "damaged/damaged2"
+ "$model" "1"
+}
diff --git a/materials/damaged/damaged2.vtf b/materials/damaged/damaged2.vtf
new file mode 100644
index 000000000..ea5d81649
Binary files /dev/null and b/materials/damaged/damaged2.vtf differ
diff --git a/materials/damaged/damaged3.vmt b/materials/damaged/damaged3.vmt
new file mode 100644
index 000000000..f21b36b1e
--- /dev/null
+++ b/materials/damaged/damaged3.vmt
@@ -0,0 +1,5 @@
+"LightmappedGeneric"
+{
+ "$basetexture" "damaged/damaged3"
+ "$model" "1"
+}
diff --git a/materials/damaged/damaged3.vtf b/materials/damaged/damaged3.vtf
new file mode 100644
index 000000000..0c8a9f209
Binary files /dev/null and b/materials/damaged/damaged3.vtf differ
diff --git a/materials/models/ammo/ammolabel_AP.vmt b/materials/models/ammo/ammolabel_ap.vmt
similarity index 100%
rename from materials/models/ammo/ammolabel_AP.vmt
rename to materials/models/ammo/ammolabel_ap.vmt
diff --git a/materials/models/ammo/ammolabel_AP.vtf b/materials/models/ammo/ammolabel_ap.vtf
similarity index 100%
rename from materials/models/ammo/ammolabel_AP.vtf
rename to materials/models/ammo/ammolabel_ap.vtf
diff --git a/materials/models/ammo/ammolabel_GL.vmt b/materials/models/ammo/ammolabel_gl.vmt
similarity index 100%
rename from materials/models/ammo/ammolabel_GL.vmt
rename to materials/models/ammo/ammolabel_gl.vmt
diff --git a/materials/models/ammo/ammolabel_GL.vtf b/materials/models/ammo/ammolabel_gl.vtf
similarity index 100%
rename from materials/models/ammo/ammolabel_GL.vtf
rename to materials/models/ammo/ammolabel_gl.vtf
diff --git a/materials/models/ammo/ammolabel_HE.vmt b/materials/models/ammo/ammolabel_he.vmt
similarity index 100%
rename from materials/models/ammo/ammolabel_HE.vmt
rename to materials/models/ammo/ammolabel_he.vmt
diff --git a/materials/models/ammo/ammolabel_HE.vtf b/materials/models/ammo/ammolabel_he.vtf
similarity index 100%
rename from materials/models/ammo/ammolabel_HE.vtf
rename to materials/models/ammo/ammolabel_he.vtf
diff --git a/materials/models/ammo/round_skin_AP.vmt b/materials/models/ammo/round_skin_ap.vmt
similarity index 100%
rename from materials/models/ammo/round_skin_AP.vmt
rename to materials/models/ammo/round_skin_ap.vmt
diff --git a/materials/models/ammo/round_skin_AP.vtf b/materials/models/ammo/round_skin_ap.vtf
similarity index 100%
rename from materials/models/ammo/round_skin_AP.vtf
rename to materials/models/ammo/round_skin_ap.vtf
diff --git a/materials/models/ammo/round_skin_HE.vmt b/materials/models/ammo/round_skin_he.vmt
similarity index 100%
rename from materials/models/ammo/round_skin_HE.vmt
rename to materials/models/ammo/round_skin_he.vmt
diff --git a/materials/models/ammo/round_skin_HE.vtf b/materials/models/ammo/round_skin_he.vtf
similarity index 100%
rename from materials/models/ammo/round_skin_HE.vtf
rename to materials/models/ammo/round_skin_he.vtf
diff --git a/materials/models/ammo/round_skin_HEAT.vmt b/materials/models/ammo/round_skin_heat.vmt
similarity index 100%
rename from materials/models/ammo/round_skin_HEAT.vmt
rename to materials/models/ammo/round_skin_heat.vmt
diff --git a/materials/models/ammo/round_skin_HEAT.vtf b/materials/models/ammo/round_skin_heat.vtf
similarity index 100%
rename from materials/models/ammo/round_skin_HEAT.vtf
rename to materials/models/ammo/round_skin_heat.vtf
diff --git a/materials/models/ammo/round_skin_IN.vmt b/materials/models/ammo/round_skin_in.vmt
similarity index 100%
rename from materials/models/ammo/round_skin_IN.vmt
rename to materials/models/ammo/round_skin_in.vmt
diff --git a/materials/models/ammo/round_skin_IN.vtf b/materials/models/ammo/round_skin_in.vtf
similarity index 100%
rename from materials/models/ammo/round_skin_IN.vtf
rename to materials/models/ammo/round_skin_in.vtf
diff --git a/materials/models/autocannon/autocannon_sheet.vmt b/materials/models/autocannon/autocannon_sheet.vmt
index 9c9a6757e..34592bb43 100644
--- a/materials/models/autocannon/autocannon_sheet.vmt
+++ b/materials/models/autocannon/autocannon_sheet.vmt
@@ -13,6 +13,7 @@
"$phongfresnelranges" "[0.5 0.5 0.5]"
"$phongexponent" "10"
"$model" 1
+ "$blendtintbybasealpha" "1"
}
diff --git a/materials/models/autocannon/autocannon_sheet.vtf b/materials/models/autocannon/autocannon_sheet.vtf
index 2d2bca935..afac9567a 100644
Binary files a/materials/models/autocannon/autocannon_sheet.vtf and b/materials/models/autocannon/autocannon_sheet.vtf differ
diff --git a/materials/models/engines/heavytran_sheet.vmt b/materials/models/engines/heavytran_sheet.vmt
index 4d5ec81c6..94cb8c2cd 100644
--- a/materials/models/engines/heavytran_sheet.vmt
+++ b/materials/models/engines/heavytran_sheet.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/engines/heavytran_sheet"
- "$bumpmap" "models/engines/heavytran_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/heavytran_sheet"
+ "$bumpmap" "models/engines/heavytran_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/heavytran_sheet.vtf b/materials/models/engines/heavytran_sheet.vtf
index 9a57653c2..ca0ce690a 100644
Binary files a/materials/models/engines/heavytran_sheet.vtf and b/materials/models/engines/heavytran_sheet.vtf differ
diff --git a/materials/models/engines/heavytran_sheet2.vmt b/materials/models/engines/heavytran_sheet2.vmt
index e9b04355f..701e4af3c 100644
--- a/materials/models/engines/heavytran_sheet2.vmt
+++ b/materials/models/engines/heavytran_sheet2.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/engines/heavytran_sheet2"
- "$bumpmap" "models/engines/heavytran_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/heavytran_sheet2"
+ "$bumpmap" "models/engines/heavytran_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/heavytran_sheet2.vtf b/materials/models/engines/heavytran_sheet2.vtf
index 264de9655..e695571ae 100644
Binary files a/materials/models/engines/heavytran_sheet2.vtf and b/materials/models/engines/heavytran_sheet2.vtf differ
diff --git a/materials/models/engines/heavytran_sheet3.vmt b/materials/models/engines/heavytran_sheet3.vmt
index 7ff332c82..53815cacd 100644
--- a/materials/models/engines/heavytran_sheet3.vmt
+++ b/materials/models/engines/heavytran_sheet3.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/engines/heavytran_sheet3"
- "$bumpmap" "models/engines/heavytran_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/heavytran_sheet3"
+ "$bumpmap" "models/engines/heavytran_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/heavytran_sheet3.vtf b/materials/models/engines/heavytran_sheet3.vtf
index 9578adc64..ba76a4b27 100644
Binary files a/materials/models/engines/heavytran_sheet3.vtf and b/materials/models/engines/heavytran_sheet3.vtf differ
diff --git a/materials/models/engines/inline6_sheet.vmt b/materials/models/engines/inline6_sheet.vmt
index ab10daa70..2d4c89f1f 100644
--- a/materials/models/engines/inline6_sheet.vmt
+++ b/materials/models/engines/inline6_sheet.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/engines/inline6_sheet"
- "$bumpmap" "models/engines/inline6_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[1 1 1]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/inline6_sheet"
+ "$bumpmap" "models/engines/inline6_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[1 1 1]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/inline6_sheet.vtf b/materials/models/engines/inline6_sheet.vtf
index 5a748a868..147b29392 100644
Binary files a/materials/models/engines/inline6_sheet.vtf and b/materials/models/engines/inline6_sheet.vtf differ
diff --git a/materials/models/engines/inline6_sheet2.vmt b/materials/models/engines/inline6_sheet2.vmt
new file mode 100644
index 000000000..f1431ede9
--- /dev/null
+++ b/materials/models/engines/inline6_sheet2.vmt
@@ -0,0 +1,19 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/inline6_sheet2"
+ "$bumpmap" "models/engines/inline6_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[1 1 1]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/inline6_sheet2.vtf b/materials/models/engines/inline6_sheet2.vtf
new file mode 100644
index 000000000..d9a2d382d
Binary files /dev/null and b/materials/models/engines/inline6_sheet2.vtf differ
diff --git a/materials/models/engines/linear_heavy_sheet.vmt b/materials/models/engines/linear_heavy_sheet.vmt
index 37ca9b1a5..5e9766a0e 100644
--- a/materials/models/engines/linear_heavy_sheet.vmt
+++ b/materials/models/engines/linear_heavy_sheet.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/engines/linear_heavy_sheet"
- "$bumpmap" "models/engines/linear_heavy_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/linear_heavy_sheet"
+ "$bumpmap" "models/engines/linear_heavy_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/linear_heavy_sheet.vtf b/materials/models/engines/linear_heavy_sheet.vtf
index 1cbdec02a..9a1bd7b15 100644
Binary files a/materials/models/engines/linear_heavy_sheet.vtf and b/materials/models/engines/linear_heavy_sheet.vtf differ
diff --git a/materials/models/engines/radial7_sheet.vmt b/materials/models/engines/radial7_sheet.vmt
index 8f607fab9..918fb18c9 100644
--- a/materials/models/engines/radial7_sheet.vmt
+++ b/materials/models/engines/radial7_sheet.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/engines/radial7_sheet"
- "$bumpmap" "models/engines/radial7_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/radial7_sheet"
+ "$bumpmap" "models/engines/radial7_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/radial7_sheet.vtf b/materials/models/engines/radial7_sheet.vtf
index 0916519ed..a097cc8f1 100644
Binary files a/materials/models/engines/radial7_sheet.vtf and b/materials/models/engines/radial7_sheet.vtf differ
diff --git a/materials/models/engines/v8_sheet.vmt b/materials/models/engines/v8_sheet.vmt
index 8c0fd6364..59efbd092 100644
--- a/materials/models/engines/v8_sheet.vmt
+++ b/materials/models/engines/v8_sheet.vmt
@@ -1,18 +1,20 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/engines/v8_sheet"
- "$bumpmap" "models/engines/v8_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/v8_sheet"
+ "$bumpmap" "models/engines/v8_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" "1"
+ "$blendtintbybasealpha" "1"
+ "$color" "{200 1 1}"
+}
+
+
diff --git a/materials/models/engines/v8_sheet.vtf b/materials/models/engines/v8_sheet.vtf
index 2133b8ddf..48e584a9c 100644
Binary files a/materials/models/engines/v8_sheet.vtf and b/materials/models/engines/v8_sheet.vtf differ
diff --git a/materials/models/engines/v8_sheet2.vmt b/materials/models/engines/v8_sheet2.vmt
new file mode 100644
index 000000000..a2dfd91c8
--- /dev/null
+++ b/materials/models/engines/v8_sheet2.vmt
@@ -0,0 +1,19 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/engines/v8_sheet2"
+ "$bumpmap" "models/engines/v8_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" "1"
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/engines/v8_sheet2.vtf b/materials/models/engines/v8_sheet2.vtf
new file mode 100644
index 000000000..3cf878ce9
Binary files /dev/null and b/materials/models/engines/v8_sheet2.vtf differ
diff --git a/materials/models/fueltank/fueltank_col_metal.vtf b/materials/models/fueltank/fueltank_col_metal.vtf
new file mode 100644
index 000000000..edcf6c0b0
Binary files /dev/null and b/materials/models/fueltank/fueltank_col_metal.vtf differ
diff --git a/materials/models/fueltank/fueltank_col_plastic.vtf b/materials/models/fueltank/fueltank_col_plastic.vtf
new file mode 100644
index 000000000..6dc1e1912
Binary files /dev/null and b/materials/models/fueltank/fueltank_col_plastic.vtf differ
diff --git a/materials/models/fueltank/fueltank_col_rust.vtf b/materials/models/fueltank/fueltank_col_rust.vtf
new file mode 100644
index 000000000..0b4234e46
Binary files /dev/null and b/materials/models/fueltank/fueltank_col_rust.vtf differ
diff --git a/materials/models/fueltank/fueltank_gloss.vmt b/materials/models/fueltank/fueltank_gloss.vmt
new file mode 100644
index 000000000..d73d6d45d
--- /dev/null
+++ b/materials/models/fueltank/fueltank_gloss.vmt
@@ -0,0 +1,14 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/fueltank/fueltank_col_plastic"
+ "$bumpmap" "models/fueltank/fueltank_nor_gloss"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.5 .5 .5]"
+
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/fueltank/fueltank_nor_gloss.vtf b/materials/models/fueltank/fueltank_nor_gloss.vtf
new file mode 100644
index 000000000..f1d9f7482
Binary files /dev/null and b/materials/models/fueltank/fueltank_nor_gloss.vtf differ
diff --git a/materials/models/fueltank/fueltank_nor_metal.vtf b/materials/models/fueltank/fueltank_nor_metal.vtf
new file mode 100644
index 000000000..9fac367ac
Binary files /dev/null and b/materials/models/fueltank/fueltank_nor_metal.vtf differ
diff --git a/materials/models/fueltank/fueltank_nor_plastic.vtf b/materials/models/fueltank/fueltank_nor_plastic.vtf
new file mode 100644
index 000000000..1e04a13d6
Binary files /dev/null and b/materials/models/fueltank/fueltank_nor_plastic.vtf differ
diff --git a/materials/models/fueltank/fueltank_nor_rust.vtf b/materials/models/fueltank/fueltank_nor_rust.vtf
new file mode 100644
index 000000000..ab9098afa
Binary files /dev/null and b/materials/models/fueltank/fueltank_nor_rust.vtf differ
diff --git a/materials/models/fueltank/fueltank_plastic.vmt b/materials/models/fueltank/fueltank_plastic.vmt
new file mode 100644
index 000000000..cb59631d1
--- /dev/null
+++ b/materials/models/fueltank/fueltank_plastic.vmt
@@ -0,0 +1,14 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/fueltank/fueltank_col_plastic"
+ "$bumpmap" "models/fueltank/fueltank_nor_plastic"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.5 .5 .5]"
+
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/fueltank/fueltank_rust.vmt b/materials/models/fueltank/fueltank_rust.vmt
new file mode 100644
index 000000000..2679f515b
--- /dev/null
+++ b/materials/models/fueltank/fueltank_rust.vmt
@@ -0,0 +1,17 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/fueltank/fueltank_col_rust"
+ "$bumpmap" "models/fueltank/fueltank_nor_rust"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/fueltank/fueltank_steel.vmt b/materials/models/fueltank/fueltank_steel.vmt
new file mode 100644
index 000000000..6094a6275
--- /dev/null
+++ b/materials/models/fueltank/fueltank_steel.vmt
@@ -0,0 +1,14 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/fueltank/fueltank_col_metal"
+ "$bumpmap" "models/fueltank/fueltank_nor_metal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.5 .5 .5]"
+
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/howitzer/howitzer_sheet.vmt b/materials/models/howitzer/howitzer_sheet.vmt
index e892bedc6..fdeeb2bc8 100644
--- a/materials/models/howitzer/howitzer_sheet.vmt
+++ b/materials/models/howitzer/howitzer_sheet.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/howitzer/howitzer_sheet"
- "$bumpmap" "models/howitzer/howitzer_sheet_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/howitzer/howitzer_sheet"
+ "$bumpmap" "models/howitzer/howitzer_sheet_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/howitzer/howitzer_sheet.vtf b/materials/models/howitzer/howitzer_sheet.vtf
index cddd33599..89a734a98 100644
Binary files a/materials/models/howitzer/howitzer_sheet.vtf and b/materials/models/howitzer/howitzer_sheet.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_001/metal red.vmt b/materials/models/jojobull/wheels/wheel_001/metal red.vmt
new file mode 100644
index 000000000..3cbd90e02
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_001/metal red.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_001/metal red"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_001/metal red.vtf b/materials/models/jojobull/wheels/wheel_001/metal red.vtf
new file mode 100644
index 000000000..5d5328c95
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_001/metal red.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_001/metal.vmt b/materials/models/jojobull/wheels/wheel_001/metal.vmt
new file mode 100644
index 000000000..21e51c55d
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_001/metal.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_001/metal"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_001/metal.vtf b/materials/models/jojobull/wheels/wheel_001/metal.vtf
new file mode 100644
index 000000000..b1c746440
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_001/metal.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_001/motor3.vmt b/materials/models/jojobull/wheels/wheel_001/motor3.vmt
new file mode 100644
index 000000000..8215365fd
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_001/motor3.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_001/motor3"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_001/motor3.vtf b/materials/models/jojobull/wheels/wheel_001/motor3.vtf
new file mode 100644
index 000000000..939beb431
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_001/motor3.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_001/quad.vmt b/materials/models/jojobull/wheels/wheel_001/quad.vmt
new file mode 100644
index 000000000..c4602ad0a
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_001/quad.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_001/quad"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_001/quad.vtf b/materials/models/jojobull/wheels/wheel_001/quad.vtf
new file mode 100644
index 000000000..38c5c86ce
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_001/quad.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_001/remschijven.vmt b/materials/models/jojobull/wheels/wheel_001/remschijven.vmt
new file mode 100644
index 000000000..c35ab1a03
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_001/remschijven.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_001/remschijven"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_001/remschijven.vtf b/materials/models/jojobull/wheels/wheel_001/remschijven.vtf
new file mode 100644
index 000000000..b84f8e7e5
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_001/remschijven.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_001/tire.vmt b/materials/models/jojobull/wheels/wheel_001/tire.vmt
new file mode 100644
index 000000000..99cc9bb76
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_001/tire.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_001/tire"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_001/tire.vtf b/materials/models/jojobull/wheels/wheel_001/tire.vtf
new file mode 100644
index 000000000..8cb4844e7
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_001/tire.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_002/FFCCCCCC.vmt b/materials/models/jojobull/wheels/wheel_002/FFCCCCCC.vmt
new file mode 100644
index 000000000..d9520bb5f
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_002/FFCCCCCC.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_002/FFCCCCCC"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_002/FFCCCCCC.vtf b/materials/models/jojobull/wheels/wheel_002/FFCCCCCC.vtf
new file mode 100644
index 000000000..c585c47d5
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_002/FFCCCCCC.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_002/brakedisk3.vmt b/materials/models/jojobull/wheels/wheel_002/brakedisk3.vmt
new file mode 100644
index 000000000..e178d01d9
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_002/brakedisk3.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_002/brakedisk3"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_002/brakedisk3.vtf b/materials/models/jojobull/wheels/wheel_002/brakedisk3.vtf
new file mode 100644
index 000000000..0470705f8
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_002/brakedisk3.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_002/rim.vmt b/materials/models/jojobull/wheels/wheel_002/rim.vmt
new file mode 100644
index 000000000..47f51ccfc
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_002/rim.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_002/rim"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_002/rim.vtf b/materials/models/jojobull/wheels/wheel_002/rim.vtf
new file mode 100644
index 000000000..20192f6cb
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_002/rim.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_002/texNFS.vmt b/materials/models/jojobull/wheels/wheel_002/texNFS.vmt
new file mode 100644
index 000000000..c57b01b63
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_002/texNFS.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_002/texNFS"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_002/texNFS.vtf b/materials/models/jojobull/wheels/wheel_002/texNFS.vtf
new file mode 100644
index 000000000..6bb1393e3
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_002/texNFS.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_002/tyre.vmt b/materials/models/jojobull/wheels/wheel_002/tyre.vmt
new file mode 100644
index 000000000..3ebcc7885
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_002/tyre.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_002/tyre"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_002/tyre.vtf b/materials/models/jojobull/wheels/wheel_002/tyre.vtf
new file mode 100644
index 000000000..631f02be5
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_002/tyre.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_003/telo.vmt b/materials/models/jojobull/wheels/wheel_003/telo.vmt
new file mode 100644
index 000000000..28293f4b8
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_003/telo.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_003/telo"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_003/telo.vtf b/materials/models/jojobull/wheels/wheel_003/telo.vtf
new file mode 100644
index 000000000..d1fc9af8a
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_003/telo.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_003/wheel.vmt b/materials/models/jojobull/wheels/wheel_003/wheel.vmt
new file mode 100644
index 000000000..7c4cf115c
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_003/wheel.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_003/wheel"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_003/wheel.vtf b/materials/models/jojobull/wheels/wheel_003/wheel.vtf
new file mode 100644
index 000000000..371d71282
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_003/wheel.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_004/tire_01.vmt b/materials/models/jojobull/wheels/wheel_004/tire_01.vmt
new file mode 100644
index 000000000..7e5bad6fc
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_004/tire_01.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_004/tire_01"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_004/tire_01.vtf b/materials/models/jojobull/wheels/wheel_004/tire_01.vtf
new file mode 100644
index 000000000..55b1655ec
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_004/tire_01.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_005/camryhubcap.vmt b/materials/models/jojobull/wheels/wheel_005/camryhubcap.vmt
new file mode 100644
index 000000000..12dc393cf
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_005/camryhubcap.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_005/camryhubcap"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_005/camryhubcap.vtf b/materials/models/jojobull/wheels/wheel_005/camryhubcap.vtf
new file mode 100644
index 000000000..eb57f8105
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_005/camryhubcap.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_005/camrytred.vmt b/materials/models/jojobull/wheels/wheel_005/camrytred.vmt
new file mode 100644
index 000000000..cc7c1acd0
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_005/camrytred.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_005/camrytred"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_005/camrytred.vtf b/materials/models/jojobull/wheels/wheel_005/camrytred.vtf
new file mode 100644
index 000000000..587a14bab
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_005/camrytred.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_005/camrytyre.vmt b/materials/models/jojobull/wheels/wheel_005/camrytyre.vmt
new file mode 100644
index 000000000..4343551de
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_005/camrytyre.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_005/camrytyre"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_005/camrytyre.vtf b/materials/models/jojobull/wheels/wheel_005/camrytyre.vtf
new file mode 100644
index 000000000..6cee13dbd
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_005/camrytyre.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_006/boeingENG.vmt b/materials/models/jojobull/wheels/wheel_006/boeingENG.vmt
new file mode 100644
index 000000000..386c911ef
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_006/boeingENG.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_006/boeingENG"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_006/boeingENG.vtf b/materials/models/jojobull/wheels/wheel_006/boeingENG.vtf
new file mode 100644
index 000000000..8f0b09852
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_006/boeingENG.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_007/FF999999.vmt b/materials/models/jojobull/wheels/wheel_007/FF999999.vmt
new file mode 100644
index 000000000..5f8028b8d
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_007/FF999999.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_007/FF999999"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_007/FF999999.vtf b/materials/models/jojobull/wheels/wheel_007/FF999999.vtf
new file mode 100644
index 000000000..4b30c518c
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_007/FF999999.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_007/FFFFFFFF.vmt b/materials/models/jojobull/wheels/wheel_007/FFFFFFFF.vmt
new file mode 100644
index 000000000..fdef0a8b5
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_007/FFFFFFFF.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_007/FFFFFFFF"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_007/FFFFFFFF.vtf b/materials/models/jojobull/wheels/wheel_007/FFFFFFFF.vtf
new file mode 100644
index 000000000..57768cf4d
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_007/FFFFFFFF.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_007/brake.vmt b/materials/models/jojobull/wheels/wheel_007/brake.vmt
new file mode 100644
index 000000000..fffbf6eb7
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_007/brake.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_007/brake"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_007/brake.vtf b/materials/models/jojobull/wheels/wheel_007/brake.vtf
new file mode 100644
index 000000000..553158a3d
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_007/brake.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_007/wheel.vmt b/materials/models/jojobull/wheels/wheel_007/wheel.vmt
new file mode 100644
index 000000000..08a4ab1d1
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_007/wheel.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_007/wheel"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_007/wheel.vtf b/materials/models/jojobull/wheels/wheel_007/wheel.vtf
new file mode 100644
index 000000000..4069fe86d
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_007/wheel.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_008/m05.vmt b/materials/models/jojobull/wheels/wheel_008/m05.vmt
new file mode 100644
index 000000000..de40be008
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_008/m05.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_008/m05"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_008/m05.vtf b/materials/models/jojobull/wheels/wheel_008/m05.vtf
new file mode 100644
index 000000000..f0a9eb073
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_008/m05.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_008/wheel1.vmt b/materials/models/jojobull/wheels/wheel_008/wheel1.vmt
new file mode 100644
index 000000000..704445892
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_008/wheel1.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_008/wheel1"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_008/wheel1.vtf b/materials/models/jojobull/wheels/wheel_008/wheel1.vtf
new file mode 100644
index 000000000..b9093b45c
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_008/wheel1.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_009/FF000000.vmt b/materials/models/jojobull/wheels/wheel_009/FF000000.vmt
new file mode 100644
index 000000000..2052dd700
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_009/FF000000.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_009/FF000000"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_009/FF000000.vtf b/materials/models/jojobull/wheels/wheel_009/FF000000.vtf
new file mode 100644
index 000000000..81b068622
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_009/FF000000.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_009/grey64.vmt b/materials/models/jojobull/wheels/wheel_009/grey64.vmt
new file mode 100644
index 000000000..8f94e4fba
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_009/grey64.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_009/grey64"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_009/grey64.vtf b/materials/models/jojobull/wheels/wheel_009/grey64.vtf
new file mode 100644
index 000000000..f67e5ccc8
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_009/grey64.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_009/gsx_by_pumbars.vmt b/materials/models/jojobull/wheels/wheel_009/gsx_by_pumbars.vmt
new file mode 100644
index 000000000..3cc9dae94
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_009/gsx_by_pumbars.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_009/gsx_by_pumbars"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_009/gsx_by_pumbars.vtf b/materials/models/jojobull/wheels/wheel_009/gsx_by_pumbars.vtf
new file mode 100644
index 000000000..74f772519
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_009/gsx_by_pumbars.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_009/tyre.vmt b/materials/models/jojobull/wheels/wheel_009/tyre.vmt
new file mode 100644
index 000000000..d287119f9
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_009/tyre.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_009/tyre"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_009/tyre.vtf b/materials/models/jojobull/wheels/wheel_009/tyre.vtf
new file mode 100644
index 000000000..6a11d97a5
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_009/tyre.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_010/tire.vmt b/materials/models/jojobull/wheels/wheel_010/tire.vmt
new file mode 100644
index 000000000..67e1e5ea1
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_010/tire.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_010/tire"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_010/tire.vtf b/materials/models/jojobull/wheels/wheel_010/tire.vtf
new file mode 100644
index 000000000..8d05a5983
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_010/tire.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_010/wheel.vmt b/materials/models/jojobull/wheels/wheel_010/wheel.vmt
new file mode 100644
index 000000000..d553c6ad2
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_010/wheel.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_010/wheel"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_010/wheel.vtf b/materials/models/jojobull/wheels/wheel_010/wheel.vtf
new file mode 100644
index 000000000..c716b4c54
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_010/wheel.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_010/wheel2.vmt b/materials/models/jojobull/wheels/wheel_010/wheel2.vmt
new file mode 100644
index 000000000..1f8c24c0a
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_010/wheel2.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_010/wheel2"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_010/wheel2.vtf b/materials/models/jojobull/wheels/wheel_010/wheel2.vtf
new file mode 100644
index 000000000..132fbf265
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_010/wheel2.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_011/contour_wheels64.vmt b/materials/models/jojobull/wheels/wheel_011/contour_wheels64.vmt
new file mode 100644
index 000000000..fbf5dc0b1
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_011/contour_wheels64.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_011/contour_wheels64"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_011/contour_wheels64.vtf b/materials/models/jojobull/wheels/wheel_011/contour_wheels64.vtf
new file mode 100644
index 000000000..4f5be4748
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_011/contour_wheels64.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_011/discs.vmt b/materials/models/jojobull/wheels/wheel_011/discs.vmt
new file mode 100644
index 000000000..209b9e09d
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_011/discs.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_011/discs"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_011/discs.vtf b/materials/models/jojobull/wheels/wheel_011/discs.vtf
new file mode 100644
index 000000000..f795979ea
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_011/discs.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_011/rim.vmt b/materials/models/jojobull/wheels/wheel_011/rim.vmt
new file mode 100644
index 000000000..55fd1d43c
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_011/rim.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_011/rim"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_011/rim.vtf b/materials/models/jojobull/wheels/wheel_011/rim.vtf
new file mode 100644
index 000000000..e0171eb85
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_011/rim.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_011/tyre64a.vmt b/materials/models/jojobull/wheels/wheel_011/tyre64a.vmt
new file mode 100644
index 000000000..e4a87534e
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_011/tyre64a.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_011/tyre64a"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_011/tyre64a.vtf b/materials/models/jojobull/wheels/wheel_011/tyre64a.vtf
new file mode 100644
index 000000000..f169467fd
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_011/tyre64a.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_012/FF1E1E1E.vmt b/materials/models/jojobull/wheels/wheel_012/FF1E1E1E.vmt
new file mode 100644
index 000000000..40d2d81f5
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_012/FF1E1E1E.vmt
@@ -0,0 +1,5 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_012/FF1E1E1E"
+ "$envmap" "env_cubemap"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_012/FF1E1E1E.vtf b/materials/models/jojobull/wheels/wheel_012/FF1E1E1E.vtf
new file mode 100644
index 000000000..57768cf4d
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_012/FF1E1E1E.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_012/tekstura.vmt b/materials/models/jojobull/wheels/wheel_012/tekstura.vmt
new file mode 100644
index 000000000..e003f7963
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_012/tekstura.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_012/tekstura"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_012/tekstura.vtf b/materials/models/jojobull/wheels/wheel_012/tekstura.vtf
new file mode 100644
index 000000000..3d711ad52
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_012/tekstura.vtf differ
diff --git a/materials/models/jojobull/wheels/wheel_012/wheel.vmt b/materials/models/jojobull/wheels/wheel_012/wheel.vmt
new file mode 100644
index 000000000..99410b81f
--- /dev/null
+++ b/materials/models/jojobull/wheels/wheel_012/wheel.vmt
@@ -0,0 +1,4 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models/jojobull/wheels/wheel_012/wheel"
+}
\ No newline at end of file
diff --git a/materials/models/jojobull/wheels/wheel_012/wheel.vtf b/materials/models/jojobull/wheels/wheel_012/wheel.vtf
new file mode 100644
index 000000000..7139fd95e
Binary files /dev/null and b/materials/models/jojobull/wheels/wheel_012/wheel.vtf differ
diff --git a/materials/models/machinegun/barrels_normal.vtf b/materials/models/machinegun/barrels_normal.vtf
new file mode 100644
index 000000000..97370c9bb
Binary files /dev/null and b/materials/models/machinegun/barrels_normal.vtf differ
diff --git a/materials/models/machinegun/barrels_sheet.vmt b/materials/models/machinegun/barrels_sheet.vmt
new file mode 100644
index 000000000..e9fe3401a
--- /dev/null
+++ b/materials/models/machinegun/barrels_sheet.vmt
@@ -0,0 +1,22 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/machinegun/barrels_sheet"
+ "$bumpmap" "models/machinegun/barrels_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
+
+
+
diff --git a/materials/models/machinegun/barrels_sheet.vtf b/materials/models/machinegun/barrels_sheet.vtf
new file mode 100644
index 000000000..19c85a0f3
Binary files /dev/null and b/materials/models/machinegun/barrels_sheet.vtf differ
diff --git a/materials/models/machinegun/receiver_normal.vtf b/materials/models/machinegun/receiver_normal.vtf
new file mode 100644
index 000000000..cbce054bd
Binary files /dev/null and b/materials/models/machinegun/receiver_normal.vtf differ
diff --git a/materials/models/machinegun/receiver_sheet.vtf b/materials/models/machinegun/receiver_sheet.vtf
new file mode 100644
index 000000000..0f4ed365c
Binary files /dev/null and b/materials/models/machinegun/receiver_sheet.vtf differ
diff --git a/materials/models/machinegun/receiver_skin.vmt b/materials/models/machinegun/receiver_skin.vmt
new file mode 100644
index 000000000..a617876e6
--- /dev/null
+++ b/materials/models/machinegun/receiver_skin.vmt
@@ -0,0 +1,18 @@
+"VertexLitGeneric"
+{
+ "$basetexture" "models/machinegun/receiver_sheet"
+ "$bumpmap" "models/machinegun/receiver_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
diff --git a/materials/models/mguns/ammo and stuff.vmt b/materials/models/mguns/ammo and stuff.vmt
new file mode 100644
index 000000000..b7fd294da
--- /dev/null
+++ b/materials/models/mguns/ammo and stuff.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/ammo and stuff"
+ $halflambert 1
+ $blendtintbybasealpha 1
+}
diff --git a/materials/models/mguns/ammo and stuff.vtf b/materials/models/mguns/ammo and stuff.vtf
new file mode 100644
index 000000000..df1f375fc
Binary files /dev/null and b/materials/models/mguns/ammo and stuff.vtf differ
diff --git a/materials/models/mguns/ammo.vmt b/materials/models/mguns/ammo.vmt
new file mode 100644
index 000000000..432c37d0b
--- /dev/null
+++ b/materials/models/mguns/ammo.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/ammo"
+ $halflambert 1
+ $blendtintbybasealpha 1
+}
diff --git a/materials/models/mguns/ammo.vtf b/materials/models/mguns/ammo.vtf
new file mode 100644
index 000000000..6781d194f
Binary files /dev/null and b/materials/models/mguns/ammo.vtf differ
diff --git a/materials/models/mguns/circles.vmt b/materials/models/mguns/circles.vmt
new file mode 100644
index 000000000..05301ab31
--- /dev/null
+++ b/materials/models/mguns/circles.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/circles"
+ "$model" "1"
+ "$translucent" "1"
+}
diff --git a/materials/models/mguns/circles.vtf b/materials/models/mguns/circles.vtf
new file mode 100644
index 000000000..9bd543a8e
Binary files /dev/null and b/materials/models/mguns/circles.vtf differ
diff --git a/materials/models/mguns/texture_barrel_mg151-20.vmt b/materials/models/mguns/texture_barrel_mg151-20.vmt
new file mode 100644
index 000000000..42793ae47
--- /dev/null
+++ b/materials/models/mguns/texture_barrel_mg151-20.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/texture_barrel_mg151-20"
+ $halflambert 1
+ $blendtintbybasealpha 1
+}
diff --git a/materials/models/mguns/texture_barrel_mg151-20.vtf b/materials/models/mguns/texture_barrel_mg151-20.vtf
new file mode 100644
index 000000000..7bcaaa29b
Binary files /dev/null and b/materials/models/mguns/texture_barrel_mg151-20.vtf differ
diff --git a/materials/models/mguns/texture_mg151-20.vmt b/materials/models/mguns/texture_mg151-20.vmt
new file mode 100644
index 000000000..ce85416e1
--- /dev/null
+++ b/materials/models/mguns/texture_mg151-20.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/texture_mg151-20"
+ $halflambert 1
+ $blendtintbybasealpha 1
+}
diff --git a/materials/models/mguns/texture_mg151-20.vtf b/materials/models/mguns/texture_mg151-20.vtf
new file mode 100644
index 000000000..04f67016e
Binary files /dev/null and b/materials/models/mguns/texture_mg151-20.vtf differ
diff --git a/materials/models/mguns/texture_mgff.vmt b/materials/models/mguns/texture_mgff.vmt
new file mode 100644
index 000000000..8b0f2b320
--- /dev/null
+++ b/materials/models/mguns/texture_mgff.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/texture_mgff"
+ $halflambert 1
+ $blendtintbybasealpha 1
+}
diff --git a/materials/models/mguns/texture_mgff.vtf b/materials/models/mguns/texture_mgff.vtf
new file mode 100644
index 000000000..31d2cd579
Binary files /dev/null and b/materials/models/mguns/texture_mgff.vtf differ
diff --git a/materials/models/mguns/texture_mgff_barrel.vmt b/materials/models/mguns/texture_mgff_barrel.vmt
new file mode 100644
index 000000000..d1751b764
--- /dev/null
+++ b/materials/models/mguns/texture_mgff_barrel.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/texture_mgff_barrel"
+ $halflambert 1
+ $blendtintbybasealpha 1
+}
diff --git a/materials/models/mguns/texture_mgff_barrel.vtf b/materials/models/mguns/texture_mgff_barrel.vtf
new file mode 100644
index 000000000..2c3fd7418
Binary files /dev/null and b/materials/models/mguns/texture_mgff_barrel.vtf differ
diff --git a/materials/models/mguns/texture_mk108.vmt b/materials/models/mguns/texture_mk108.vmt
new file mode 100644
index 000000000..e0fecab4f
--- /dev/null
+++ b/materials/models/mguns/texture_mk108.vmt
@@ -0,0 +1,6 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\mguns/texture_mk108"
+ $halflambert 1
+ $blendtintbybasealpha 1
+}
diff --git a/materials/models/mguns/texture_mk108.vtf b/materials/models/mguns/texture_mk108.vtf
new file mode 100644
index 000000000..0d956dda1
Binary files /dev/null and b/materials/models/mguns/texture_mk108.vtf differ
diff --git a/materials/models/missiles/AIM120.vmt b/materials/models/missiles/aim120.vmt
similarity index 100%
rename from materials/models/missiles/AIM120.vmt
rename to materials/models/missiles/aim120.vmt
diff --git a/materials/models/missiles/AIM120.vtf b/materials/models/missiles/aim120.vtf
similarity index 100%
rename from materials/models/missiles/AIM120.vtf
rename to materials/models/missiles/aim120.vtf
diff --git a/materials/models/missiles/AIM54.vmt b/materials/models/missiles/aim54.vmt
similarity index 100%
rename from materials/models/missiles/AIM54.vmt
rename to materials/models/missiles/aim54.vmt
diff --git a/materials/models/missiles/AIM54.vtf b/materials/models/missiles/aim54.vtf
similarity index 100%
rename from materials/models/missiles/AIM54.vtf
rename to materials/models/missiles/aim54.vtf
diff --git a/materials/models/missiles/AIM9.vmt b/materials/models/missiles/aim9.vmt
similarity index 100%
rename from materials/models/missiles/AIM9.vmt
rename to materials/models/missiles/aim9.vmt
diff --git a/materials/models/missiles/AIM9.vtf b/materials/models/missiles/aim9.vtf
similarity index 100%
rename from materials/models/missiles/AIM9.vtf
rename to materials/models/missiles/aim9.vtf
diff --git a/materials/models/missiles/FAB250.vmt b/materials/models/missiles/fab250.vmt
similarity index 100%
rename from materials/models/missiles/FAB250.vmt
rename to materials/models/missiles/fab250.vmt
diff --git a/materials/models/missiles/FAB250.vtf b/materials/models/missiles/fab250.vtf
similarity index 100%
rename from materials/models/missiles/FAB250.vtf
rename to materials/models/missiles/fab250.vtf
diff --git a/materials/models/missiles/GBU12.vmt b/materials/models/missiles/gbu12.vmt
similarity index 100%
rename from materials/models/missiles/GBU12.vmt
rename to materials/models/missiles/gbu12.vmt
diff --git a/materials/models/missiles/GBU12.vtf b/materials/models/missiles/gbu12.vtf
similarity index 100%
rename from materials/models/missiles/GBU12.vtf
rename to materials/models/missiles/gbu12.vtf
diff --git a/materials/models/missiles/GBU12_bump.vtf b/materials/models/missiles/gbu12_bump.vtf
similarity index 100%
rename from materials/models/missiles/GBU12_bump.vtf
rename to materials/models/missiles/gbu12_bump.vtf
diff --git a/materials/models/rotarycannon/kw/RAC_05x05_d1.vtf b/materials/models/rotarycannon/kw/RAC_05x05_d1.vtf
new file mode 100644
index 000000000..cfd22ee25
Binary files /dev/null and b/materials/models/rotarycannon/kw/RAC_05x05_d1.vtf differ
diff --git a/materials/models/rotarycannon/kw/RAC_05x05_n1.vtf b/materials/models/rotarycannon/kw/RAC_05x05_n1.vtf
new file mode 100644
index 000000000..c84074d05
Binary files /dev/null and b/materials/models/rotarycannon/kw/RAC_05x05_n1.vtf differ
diff --git a/materials/models/rotarycannon/kw/RAC_2048-1024.vmt b/materials/models/rotarycannon/kw/RAC_2048-1024.vmt
new file mode 100644
index 000000000..b5897e75e
--- /dev/null
+++ b/materials/models/rotarycannon/kw/RAC_2048-1024.vmt
@@ -0,0 +1,18 @@
+"VertexLitGeneric"
+{
+
+ $basetexture "models/rotarycannon/kw/RAC_2x1_d1"
+ $envmapmask "models/rotarycannon/kw/RAC_2x1_n1"
+ $bumpmap "models/rotarycannon/kw/RAC_2x1_n1"
+
+ "$surfaceprop" "metal"
+ "$phong" "1"
+ "$phongboost" "0.75"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "8"
+
+// $envmap "env_cubemap"
+ $normalmapalphaenvmapmask "1"
+ $blendtintbybasealpha "1"
+
+}
\ No newline at end of file
diff --git a/materials/models/rotarycannon/kw/RAC_2x1_d1.vtf b/materials/models/rotarycannon/kw/RAC_2x1_d1.vtf
new file mode 100644
index 000000000..73f1a1aab
Binary files /dev/null and b/materials/models/rotarycannon/kw/RAC_2x1_d1.vtf differ
diff --git a/materials/models/rotarycannon/kw/RAC_2x1_n1.vtf b/materials/models/rotarycannon/kw/RAC_2x1_n1.vtf
new file mode 100644
index 000000000..588a477f5
Binary files /dev/null and b/materials/models/rotarycannon/kw/RAC_2x1_n1.vtf differ
diff --git a/materials/models/rotarycannon/kw/RAC_512.vmt b/materials/models/rotarycannon/kw/RAC_512.vmt
new file mode 100644
index 000000000..fe0feed1e
--- /dev/null
+++ b/materials/models/rotarycannon/kw/RAC_512.vmt
@@ -0,0 +1,17 @@
+"VertexLitGeneric"
+{
+
+ $basetexture "models/rotarycannon/kw/RAC_05x05_d1"
+ $envmapmask "models/rotarycannon/kw/RAC_05x05_n1"
+ $bumpmap "models/rotarycannon/kw/RAC_05x05_n1"
+
+ "$surfaceprop" "metal"
+ "$phong" "1"
+ "$phongboost" "0.75"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "8"
+
+// $envmap "env_cubemap"
+ $normalmapalphaenvmapmask "1"
+ $alphatest "1"
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/3spokemap.vmt b/materials/models/steeringwheels/3spokemap.vmt
new file mode 100644
index 000000000..74435cfb3
--- /dev/null
+++ b/materials/models/steeringwheels/3spokemap.vmt
@@ -0,0 +1,9 @@
+VertexLitGeneric
+{
+ "$baseTexture" "models\steeringwheels\3spokemap.vtf"
+ "$phong" "1"
+ "$bumpmap" "models\steeringwheels\3spokemap_bump.vtf"
+ "$phongexponent" "5"
+ "$phongboost" "1.0"
+ "$phongfresnelranges" "[1.25 1.8 2.5]"
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/3spokemap.vtf b/materials/models/steeringwheels/3spokemap.vtf
new file mode 100644
index 000000000..95cdc801d
Binary files /dev/null and b/materials/models/steeringwheels/3spokemap.vtf differ
diff --git a/materials/models/steeringwheels/3spokemap_bump.vtf b/materials/models/steeringwheels/3spokemap_bump.vtf
new file mode 100644
index 000000000..e6fbfc0f0
Binary files /dev/null and b/materials/models/steeringwheels/3spokemap_bump.vtf differ
diff --git a/materials/models/steeringwheels/3spokemap_ref.vtf b/materials/models/steeringwheels/3spokemap_ref.vtf
new file mode 100644
index 000000000..e1c1bb0aa
Binary files /dev/null and b/materials/models/steeringwheels/3spokemap_ref.vtf differ
diff --git a/materials/models/steeringwheels/buickmap.vmt b/materials/models/steeringwheels/buickmap.vmt
new file mode 100644
index 000000000..34003ec24
--- /dev/null
+++ b/materials/models/steeringwheels/buickmap.vmt
@@ -0,0 +1,6 @@
+VertexLitGeneric
+{
+ "$baseTexture" "models\steeringwheels\buickmap.vtf"
+ "$envmap" "env_cubemap"
+ "$envmapmask" "models\steeringwheels\buickmap_ref.vtf"
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/buickmap.vtf b/materials/models/steeringwheels/buickmap.vtf
new file mode 100644
index 000000000..dcf7a49a5
Binary files /dev/null and b/materials/models/steeringwheels/buickmap.vtf differ
diff --git a/materials/models/steeringwheels/buickmap_ref.vtf b/materials/models/steeringwheels/buickmap_ref.vtf
new file mode 100644
index 000000000..02b91018b
Binary files /dev/null and b/materials/models/steeringwheels/buickmap_ref.vtf differ
diff --git a/materials/models/steeringwheels/dodgemap.vmt b/materials/models/steeringwheels/dodgemap.vmt
new file mode 100644
index 000000000..2cef51bf7
--- /dev/null
+++ b/materials/models/steeringwheels/dodgemap.vmt
@@ -0,0 +1,6 @@
+VertexLitGeneric
+{
+ "$baseTexture" "models\steeringwheels\dodgemap.vtf"
+ "$envmap" "env_cubemap"
+ "$envmapmask" "models\steeringwheels\dodgemap_ref.vtf"
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/dodgemap.vtf b/materials/models/steeringwheels/dodgemap.vtf
new file mode 100644
index 000000000..f38bde5b7
Binary files /dev/null and b/materials/models/steeringwheels/dodgemap.vtf differ
diff --git a/materials/models/steeringwheels/dodgemap_ref.vtf b/materials/models/steeringwheels/dodgemap_ref.vtf
new file mode 100644
index 000000000..43d239b26
Binary files /dev/null and b/materials/models/steeringwheels/dodgemap_ref.vtf differ
diff --git a/materials/models/steeringwheels/familymap.vmt b/materials/models/steeringwheels/familymap.vmt
new file mode 100644
index 000000000..cd26cf344
--- /dev/null
+++ b/materials/models/steeringwheels/familymap.vmt
@@ -0,0 +1,9 @@
+VertexLitGeneric
+{
+ "$baseTexture" "models\steeringwheels\familymap.vtf"
+ "$phong" "1"
+ "$bumpmap" "models\steeringwheels\familymap_bump.vtf"
+ "$phongexponent" "5"
+ "$phongboost" "1.0"
+ "$phongfresnelranges" "[1.25 1.8 2.5]"
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/familymap.vtf b/materials/models/steeringwheels/familymap.vtf
new file mode 100644
index 000000000..b0963a875
Binary files /dev/null and b/materials/models/steeringwheels/familymap.vtf differ
diff --git a/materials/models/steeringwheels/familymap_bump.vtf b/materials/models/steeringwheels/familymap_bump.vtf
new file mode 100644
index 000000000..50b5900cc
Binary files /dev/null and b/materials/models/steeringwheels/familymap_bump.vtf differ
diff --git a/materials/models/steeringwheels/fordmap.vmt b/materials/models/steeringwheels/fordmap.vmt
new file mode 100644
index 000000000..528431340
--- /dev/null
+++ b/materials/models/steeringwheels/fordmap.vmt
@@ -0,0 +1,9 @@
+VertexLitGeneric
+{
+ "$baseTexture" "models\steeringwheels\fordmap.vtf"
+ "$phong" "1"
+ "$bumpmap" "models\steeringwheels\fordmap_bump.vtf"
+ "$phongexponent" "5"
+ "$phongboost" "1.25"
+ "$phongfresnelranges" "[1 1.5 2]"
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/fordmap.vtf b/materials/models/steeringwheels/fordmap.vtf
new file mode 100644
index 000000000..1a4d071a6
Binary files /dev/null and b/materials/models/steeringwheels/fordmap.vtf differ
diff --git a/materials/models/steeringwheels/fordmap_bump.vtf b/materials/models/steeringwheels/fordmap_bump.vtf
new file mode 100644
index 000000000..37194106c
Binary files /dev/null and b/materials/models/steeringwheels/fordmap_bump.vtf differ
diff --git a/materials/models/steeringwheels/lambomap.vmt b/materials/models/steeringwheels/lambomap.vmt
new file mode 100644
index 000000000..3fa9e5b0f
--- /dev/null
+++ b/materials/models/steeringwheels/lambomap.vmt
@@ -0,0 +1,6 @@
+VertexLitGeneric
+{
+ "$baseTexture" "models\steeringwheels\lambomap.vtf"
+ "$envmap" "env_cubemap"
+ "$envmapmask" "models\steeringwheels\lambomap_ref.vtf"
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/lambomap.vtf b/materials/models/steeringwheels/lambomap.vtf
new file mode 100644
index 000000000..77b69d606
Binary files /dev/null and b/materials/models/steeringwheels/lambomap.vtf differ
diff --git a/materials/models/steeringwheels/lambomap_ref.vtf b/materials/models/steeringwheels/lambomap_ref.vtf
new file mode 100644
index 000000000..e41dd7705
Binary files /dev/null and b/materials/models/steeringwheels/lambomap_ref.vtf differ
diff --git a/materials/models/steeringwheels/truckmap.vmt b/materials/models/steeringwheels/truckmap.vmt
new file mode 100644
index 000000000..1a30d4b5f
--- /dev/null
+++ b/materials/models/steeringwheels/truckmap.vmt
@@ -0,0 +1,13 @@
+VertexLitGeneric
+{
+ "$baseTexture" "models\steeringwheels\truckmap.vtf"
+ "$envmap" "env_cubemap"
+ "$envmaptint" "[0.25 0.257 0.264]"
+ "$normalmapalphaenvmapmask" "1"
+ "$phong" "1"
+ "$bumpmap" "models\steeringwheels\truckmap_bump.vtf"
+ "$phongexponent" "15"
+ "$phongboost" "1.0"
+ "$phongfresnelranges" "[1.25 1.8 2.5]"
+
+}
\ No newline at end of file
diff --git a/materials/models/steeringwheels/truckmap.vtf b/materials/models/steeringwheels/truckmap.vtf
new file mode 100644
index 000000000..b8e8405b1
Binary files /dev/null and b/materials/models/steeringwheels/truckmap.vtf differ
diff --git a/materials/models/steeringwheels/truckmap_bump.vtf b/materials/models/steeringwheels/truckmap_bump.vtf
new file mode 100644
index 000000000..bbab9775d
Binary files /dev/null and b/materials/models/steeringwheels/truckmap_bump.vtf differ
diff --git a/materials/models/tankgun/rfling_bump.vmt b/materials/models/tankgun/rfling_bump.vmt
new file mode 100644
index 000000000..826e8b7f2
--- /dev/null
+++ b/materials/models/tankgun/rfling_bump.vmt
@@ -0,0 +1,8 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\tankgun/rfling_bump"
+ "$bumpmap" "models\tankgun/rfling_bump"
+ "$model" "1"
+ "$envmap" "env_cubemap"
+ "$selfillum_envmapmask_alpha" "1"
+}
diff --git a/materials/models/tankgun/rfling_bump.vtf b/materials/models/tankgun/rfling_bump.vtf
new file mode 100644
index 000000000..afbbca69f
Binary files /dev/null and b/materials/models/tankgun/rfling_bump.vtf differ
diff --git a/materials/models/tankgun/rifling.vmt b/materials/models/tankgun/rifling.vmt
new file mode 100644
index 000000000..76e56fd3f
--- /dev/null
+++ b/materials/models/tankgun/rifling.vmt
@@ -0,0 +1,15 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\tankgun/rifling"
+ "$bumpmap" "models\tankgun/rfling_bump"
+ "$phong" "1"
+ "$phongexponent" "10"
+ "$phongboost" ".1"
+ "$phongfresnelranges" "[0 1 20]"
+ "$rimlight" "0"
+ "$rimlightexponent" "1"
+ "$rimlightboost" ".1"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmap" "models\tankgun/rifling_sm"
+ "$envmaptint" "[.005 .005 .005]"
+}
diff --git a/materials/models/tankgun/rifling.vtf b/materials/models/tankgun/rifling.vtf
new file mode 100644
index 000000000..00b9fccec
Binary files /dev/null and b/materials/models/tankgun/rifling.vtf differ
diff --git a/materials/models/tankgun/rifling_sm.vmt b/materials/models/tankgun/rifling_sm.vmt
new file mode 100644
index 000000000..52a70977b
--- /dev/null
+++ b/materials/models/tankgun/rifling_sm.vmt
@@ -0,0 +1,8 @@
+"VertexLitGeneric"
+{
+ "$baseTexture" "models\tankgun/rifling_sm"
+ "$bumpmap" "models\tankgun/rfling_bump"
+ "$model" "1"
+ "$envmap" "env_cubemap"
+ "$selfillum_envmapmask_alpha" "1"
+}
diff --git a/materials/models/tankgun/rifling_sm.vtf b/materials/models/tankgun/rifling_sm.vtf
new file mode 100644
index 000000000..6ae898127
Binary files /dev/null and b/materials/models/tankgun/rifling_sm.vtf differ
diff --git a/materials/models/tankgun/tankgun_sheet2.vmt b/materials/models/tankgun/tankgun_sheet2.vmt
index 248d2a778..8720eb3e8 100644
--- a/materials/models/tankgun/tankgun_sheet2.vmt
+++ b/materials/models/tankgun/tankgun_sheet2.vmt
@@ -1,18 +1,19 @@
-"VertexLitGeneric"
-{
- "$basetexture" "models/tankgun/tankgun_sheet2"
- "$bumpmap" "models/tankgun/tankgun_sheet2_normal"
- "$surfaceprop" "metal"
- "$envmap" "env_cubemap"
- "$normalmapalphaenvmapmask" "1"
- "$envmaptint" "[.01 .01 .01]"
- "$envmapcontrast" .1
- "$envmapsaturation" 0.1
- "$phong" "1"
- "$phongboost" "0.1"
- "$phongfresnelranges" "[0.5 0.5 0.5]"
- "$phongexponent" "10"
- "$model" 1
-}
-
-
+"VertexLitGeneric"
+{
+ "$basetexture" "models/tankgun/tankgun_sheet2"
+ "$bumpmap" "models/tankgun/tankgun_sheet2_normal"
+ "$surfaceprop" "metal"
+ "$envmap" "env_cubemap"
+ "$normalmapalphaenvmapmask" "1"
+ "$envmaptint" "[.01 .01 .01]"
+ "$envmapcontrast" .1
+ "$envmapsaturation" 0.1
+ "$phong" "1"
+ "$phongboost" "0.1"
+ "$phongfresnelranges" "[0.5 0.5 0.5]"
+ "$phongexponent" "10"
+ "$model" 1
+ "$blendtintbybasealpha" "1"
+}
+
+
diff --git a/materials/models/tankgun/tankgun_sheet2.vtf b/materials/models/tankgun/tankgun_sheet2.vtf
index ea548bff6..c918d6332 100644
Binary files a/materials/models/tankgun/tankgun_sheet2.vtf and b/materials/models/tankgun/tankgun_sheet2.vtf differ
diff --git a/materials/models/weapons/V_sniper/amr_lens.vmt b/materials/models/weapons/v_sniper/amr_lens.vmt
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_lens.vmt
rename to materials/models/weapons/v_sniper/amr_lens.vmt
diff --git a/materials/models/weapons/V_sniper/amr_lens.vtf b/materials/models/weapons/v_sniper/amr_lens.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_lens.vtf
rename to materials/models/weapons/v_sniper/amr_lens.vtf
diff --git a/materials/models/weapons/V_sniper/amr_lens_Normal.vtf b/materials/models/weapons/v_sniper/amr_lens_normal.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_lens_Normal.vtf
rename to materials/models/weapons/v_sniper/amr_lens_normal.vtf
diff --git a/materials/models/weapons/V_sniper/amr_rendertarget.vmt b/materials/models/weapons/v_sniper/amr_rendertarget.vmt
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_rendertarget.vmt
rename to materials/models/weapons/v_sniper/amr_rendertarget.vmt
diff --git a/materials/models/weapons/V_sniper/amr_scope.vmt b/materials/models/weapons/v_sniper/amr_scope.vmt
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_scope.vmt
rename to materials/models/weapons/v_sniper/amr_scope.vmt
diff --git a/materials/models/weapons/V_sniper/amr_scope_sheet.vmt b/materials/models/weapons/v_sniper/amr_scope_sheet.vmt
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_scope_sheet.vmt
rename to materials/models/weapons/v_sniper/amr_scope_sheet.vmt
diff --git a/materials/models/weapons/V_sniper/amr_scope_sheet.vtf b/materials/models/weapons/v_sniper/amr_scope_sheet.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_scope_sheet.vtf
rename to materials/models/weapons/v_sniper/amr_scope_sheet.vtf
diff --git a/materials/models/weapons/V_sniper/amr_scope_sheet_normal.vtf b/materials/models/weapons/v_sniper/amr_scope_sheet_normal.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_scope_sheet_normal.vtf
rename to materials/models/weapons/v_sniper/amr_scope_sheet_normal.vtf
diff --git a/materials/models/weapons/V_sniper/amr_sheet1.vmt b/materials/models/weapons/v_sniper/amr_sheet1.vmt
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_sheet1.vmt
rename to materials/models/weapons/v_sniper/amr_sheet1.vmt
diff --git a/materials/models/weapons/V_sniper/amr_sheet1.vtf b/materials/models/weapons/v_sniper/amr_sheet1.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_sheet1.vtf
rename to materials/models/weapons/v_sniper/amr_sheet1.vtf
diff --git a/materials/models/weapons/V_sniper/amr_sheet1_normal.vtf b/materials/models/weapons/v_sniper/amr_sheet1_normal.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_sheet1_normal.vtf
rename to materials/models/weapons/v_sniper/amr_sheet1_normal.vtf
diff --git a/materials/models/weapons/V_sniper/amr_sheet2.vmt b/materials/models/weapons/v_sniper/amr_sheet2.vmt
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_sheet2.vmt
rename to materials/models/weapons/v_sniper/amr_sheet2.vmt
diff --git a/materials/models/weapons/V_sniper/amr_sheet2.vtf b/materials/models/weapons/v_sniper/amr_sheet2.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_sheet2.vtf
rename to materials/models/weapons/v_sniper/amr_sheet2.vtf
diff --git a/materials/models/weapons/V_sniper/amr_sheet2_normal.vtf b/materials/models/weapons/v_sniper/amr_sheet2_normal.vtf
similarity index 100%
rename from materials/models/weapons/V_sniper/amr_sheet2_normal.vtf
rename to materials/models/weapons/v_sniper/amr_sheet2_normal.vtf
diff --git a/materials/models/weapons/W_sniper/w_amr_sheet.vmt b/materials/models/weapons/w_sniper/w_amr_sheet.vmt
similarity index 100%
rename from materials/models/weapons/W_sniper/w_amr_sheet.vmt
rename to materials/models/weapons/w_sniper/w_amr_sheet.vmt
diff --git a/materials/models/weapons/W_sniper/w_amr_sheet.vtf b/materials/models/weapons/w_sniper/w_amr_sheet.vtf
similarity index 100%
rename from materials/models/weapons/W_sniper/w_amr_sheet.vtf
rename to materials/models/weapons/w_sniper/w_amr_sheet.vtf
diff --git a/materials/models/weapons/W_sniper/w_amr_sheet_normal.vtf b/materials/models/weapons/w_sniper/w_amr_sheet_normal.vtf
similarity index 100%
rename from materials/models/weapons/W_sniper/w_amr_sheet_normal.vtf
rename to materials/models/weapons/w_sniper/w_amr_sheet_normal.vtf
diff --git a/materials/sprites/acf_tracer.vmt b/materials/sprites/acf_tracer.vmt
new file mode 100644
index 000000000..32b3693e6
--- /dev/null
+++ b/materials/sprites/acf_tracer.vmt
@@ -0,0 +1,8 @@
+"UnlitGeneric"
+{
+ "$baseTexture" "sprites/acf_tracer"
+
+ "$additive" 1
+ "$vertexcolor" 1
+ "$vertexalpha" 1
+}
\ No newline at end of file
diff --git a/materials/sprites/acf_tracer.vtf b/materials/sprites/acf_tracer.vtf
new file mode 100644
index 000000000..8cae2424b
Binary files /dev/null and b/materials/sprites/acf_tracer.vtf differ
diff --git a/models/ammocrates/ammo_1x1x2.dx80.vtx b/models/ammocrates/ammo_1x1x2.dx80.vtx
new file mode 100644
index 000000000..3006f2da3
Binary files /dev/null and b/models/ammocrates/ammo_1x1x2.dx80.vtx differ
diff --git a/models/ammocrates/ammo_1x1x2.dx90.vtx b/models/ammocrates/ammo_1x1x2.dx90.vtx
new file mode 100644
index 000000000..b506d8b06
Binary files /dev/null and b/models/ammocrates/ammo_1x1x2.dx90.vtx differ
diff --git a/models/ammocrates/ammo_1x1x2.mdl b/models/ammocrates/ammo_1x1x2.mdl
new file mode 100644
index 000000000..93cc66ea3
Binary files /dev/null and b/models/ammocrates/ammo_1x1x2.mdl differ
diff --git a/models/ammocrates/ammo_1x1x2.phy b/models/ammocrates/ammo_1x1x2.phy
new file mode 100644
index 000000000..444a959a8
Binary files /dev/null and b/models/ammocrates/ammo_1x1x2.phy differ
diff --git a/models/ammocrates/ammo_1x1x2.sw.vtx b/models/ammocrates/ammo_1x1x2.sw.vtx
new file mode 100644
index 000000000..80f09a2cd
Binary files /dev/null and b/models/ammocrates/ammo_1x1x2.sw.vtx differ
diff --git a/models/ammocrates/ammo_1x1x2.vvd b/models/ammocrates/ammo_1x1x2.vvd
new file mode 100644
index 000000000..8a4a778ad
Binary files /dev/null and b/models/ammocrates/ammo_1x1x2.vvd differ
diff --git a/models/ammocrates/ammo_1x1x4.dx80.vtx b/models/ammocrates/ammo_1x1x4.dx80.vtx
new file mode 100644
index 000000000..e1eac210b
Binary files /dev/null and b/models/ammocrates/ammo_1x1x4.dx80.vtx differ
diff --git a/models/ammocrates/ammo_1x1x4.dx90.vtx b/models/ammocrates/ammo_1x1x4.dx90.vtx
new file mode 100644
index 000000000..a7c1e9100
Binary files /dev/null and b/models/ammocrates/ammo_1x1x4.dx90.vtx differ
diff --git a/models/ammocrates/ammo_1x1x4.mdl b/models/ammocrates/ammo_1x1x4.mdl
new file mode 100644
index 000000000..e54cedf07
Binary files /dev/null and b/models/ammocrates/ammo_1x1x4.mdl differ
diff --git a/models/ammocrates/ammo_1x1x4.phy b/models/ammocrates/ammo_1x1x4.phy
new file mode 100644
index 000000000..abb81566f
Binary files /dev/null and b/models/ammocrates/ammo_1x1x4.phy differ
diff --git a/models/ammocrates/ammo_1x1x4.sw.vtx b/models/ammocrates/ammo_1x1x4.sw.vtx
new file mode 100644
index 000000000..78d56b6db
Binary files /dev/null and b/models/ammocrates/ammo_1x1x4.sw.vtx differ
diff --git a/models/ammocrates/ammo_1x1x4.vvd b/models/ammocrates/ammo_1x1x4.vvd
new file mode 100644
index 000000000..b75376024
Binary files /dev/null and b/models/ammocrates/ammo_1x1x4.vvd differ
diff --git a/models/ammocrates/ammo_1x1x6.dx80.vtx b/models/ammocrates/ammo_1x1x6.dx80.vtx
new file mode 100644
index 000000000..4574c9470
Binary files /dev/null and b/models/ammocrates/ammo_1x1x6.dx80.vtx differ
diff --git a/models/ammocrates/ammo_1x1x6.dx90.vtx b/models/ammocrates/ammo_1x1x6.dx90.vtx
new file mode 100644
index 000000000..3a2b2cc37
Binary files /dev/null and b/models/ammocrates/ammo_1x1x6.dx90.vtx differ
diff --git a/models/ammocrates/ammo_1x1x6.mdl b/models/ammocrates/ammo_1x1x6.mdl
new file mode 100644
index 000000000..fbed5352a
Binary files /dev/null and b/models/ammocrates/ammo_1x1x6.mdl differ
diff --git a/models/ammocrates/ammo_1x1x6.phy b/models/ammocrates/ammo_1x1x6.phy
new file mode 100644
index 000000000..2fdbb6370
Binary files /dev/null and b/models/ammocrates/ammo_1x1x6.phy differ
diff --git a/models/ammocrates/ammo_1x1x6.sw.vtx b/models/ammocrates/ammo_1x1x6.sw.vtx
new file mode 100644
index 000000000..de04eb76d
Binary files /dev/null and b/models/ammocrates/ammo_1x1x6.sw.vtx differ
diff --git a/models/ammocrates/ammo_1x1x6.vvd b/models/ammocrates/ammo_1x1x6.vvd
new file mode 100644
index 000000000..71fdf11b0
Binary files /dev/null and b/models/ammocrates/ammo_1x1x6.vvd differ
diff --git a/models/ammocrates/ammo_1x1x8.dx80.vtx b/models/ammocrates/ammo_1x1x8.dx80.vtx
new file mode 100644
index 000000000..8dc623312
Binary files /dev/null and b/models/ammocrates/ammo_1x1x8.dx80.vtx differ
diff --git a/models/ammocrates/ammo_1x1x8.dx90.vtx b/models/ammocrates/ammo_1x1x8.dx90.vtx
new file mode 100644
index 000000000..88c4092fc
Binary files /dev/null and b/models/ammocrates/ammo_1x1x8.dx90.vtx differ
diff --git a/models/ammocrates/ammo_1x1x8.mdl b/models/ammocrates/ammo_1x1x8.mdl
new file mode 100644
index 000000000..42b014056
Binary files /dev/null and b/models/ammocrates/ammo_1x1x8.mdl differ
diff --git a/models/ammocrates/ammo_1x1x8.phy b/models/ammocrates/ammo_1x1x8.phy
new file mode 100644
index 000000000..b3d7a7d4a
Binary files /dev/null and b/models/ammocrates/ammo_1x1x8.phy differ
diff --git a/models/ammocrates/ammo_1x1x8.sw.vtx b/models/ammocrates/ammo_1x1x8.sw.vtx
new file mode 100644
index 000000000..7684e6245
Binary files /dev/null and b/models/ammocrates/ammo_1x1x8.sw.vtx differ
diff --git a/models/ammocrates/ammo_1x1x8.vvd b/models/ammocrates/ammo_1x1x8.vvd
new file mode 100644
index 000000000..26852fcb5
Binary files /dev/null and b/models/ammocrates/ammo_1x1x8.vvd differ
diff --git a/models/ammocrates/ammo_2x2x6.dx80.vtx b/models/ammocrates/ammo_2x2x6.dx80.vtx
new file mode 100644
index 000000000..f6b855b63
Binary files /dev/null and b/models/ammocrates/ammo_2x2x6.dx80.vtx differ
diff --git a/models/ammocrates/ammo_2x2x6.dx90.vtx b/models/ammocrates/ammo_2x2x6.dx90.vtx
new file mode 100644
index 000000000..37bca1014
Binary files /dev/null and b/models/ammocrates/ammo_2x2x6.dx90.vtx differ
diff --git a/models/ammocrates/ammo_2x2x6.mdl b/models/ammocrates/ammo_2x2x6.mdl
new file mode 100644
index 000000000..fdfc6a175
Binary files /dev/null and b/models/ammocrates/ammo_2x2x6.mdl differ
diff --git a/models/ammocrates/ammo_2x2x6.phy b/models/ammocrates/ammo_2x2x6.phy
new file mode 100644
index 000000000..ffd3b0388
Binary files /dev/null and b/models/ammocrates/ammo_2x2x6.phy differ
diff --git a/models/ammocrates/ammo_2x2x6.sw.vtx b/models/ammocrates/ammo_2x2x6.sw.vtx
new file mode 100644
index 000000000..55ff3f8d2
Binary files /dev/null and b/models/ammocrates/ammo_2x2x6.sw.vtx differ
diff --git a/models/ammocrates/ammo_2x2x6.vvd b/models/ammocrates/ammo_2x2x6.vvd
new file mode 100644
index 000000000..13f69e308
Binary files /dev/null and b/models/ammocrates/ammo_2x2x6.vvd differ
diff --git a/models/ammocrates/ammo_2x2x8.dx80.vtx b/models/ammocrates/ammo_2x2x8.dx80.vtx
new file mode 100644
index 000000000..28b9c7f4a
Binary files /dev/null and b/models/ammocrates/ammo_2x2x8.dx80.vtx differ
diff --git a/models/ammocrates/ammo_2x2x8.dx90.vtx b/models/ammocrates/ammo_2x2x8.dx90.vtx
new file mode 100644
index 000000000..26e71f148
Binary files /dev/null and b/models/ammocrates/ammo_2x2x8.dx90.vtx differ
diff --git a/models/ammocrates/ammo_2x2x8.mdl b/models/ammocrates/ammo_2x2x8.mdl
new file mode 100644
index 000000000..2348749fe
Binary files /dev/null and b/models/ammocrates/ammo_2x2x8.mdl differ
diff --git a/models/ammocrates/ammo_2x2x8.phy b/models/ammocrates/ammo_2x2x8.phy
new file mode 100644
index 000000000..148e5a3a5
Binary files /dev/null and b/models/ammocrates/ammo_2x2x8.phy differ
diff --git a/models/ammocrates/ammo_2x2x8.sw.vtx b/models/ammocrates/ammo_2x2x8.sw.vtx
new file mode 100644
index 000000000..81651b2df
Binary files /dev/null and b/models/ammocrates/ammo_2x2x8.sw.vtx differ
diff --git a/models/ammocrates/ammo_2x2x8.vvd b/models/ammocrates/ammo_2x2x8.vvd
new file mode 100644
index 000000000..44869d208
Binary files /dev/null and b/models/ammocrates/ammo_2x2x8.vvd differ
diff --git a/models/ammocrates/ammo_4x4x1.dx80.vtx b/models/ammocrates/ammo_4x4x1.dx80.vtx
new file mode 100644
index 000000000..46a53b4fa
Binary files /dev/null and b/models/ammocrates/ammo_4x4x1.dx80.vtx differ
diff --git a/models/ammocrates/ammo_4x4x1.dx90.vtx b/models/ammocrates/ammo_4x4x1.dx90.vtx
new file mode 100644
index 000000000..61ad3bf4a
Binary files /dev/null and b/models/ammocrates/ammo_4x4x1.dx90.vtx differ
diff --git a/models/ammocrates/ammo_4x4x1.mdl b/models/ammocrates/ammo_4x4x1.mdl
new file mode 100644
index 000000000..a99f96e9f
Binary files /dev/null and b/models/ammocrates/ammo_4x4x1.mdl differ
diff --git a/models/ammocrates/ammo_4x4x1.phy b/models/ammocrates/ammo_4x4x1.phy
new file mode 100644
index 000000000..e64794c05
Binary files /dev/null and b/models/ammocrates/ammo_4x4x1.phy differ
diff --git a/models/ammocrates/ammo_4x4x1.sw.vtx b/models/ammocrates/ammo_4x4x1.sw.vtx
new file mode 100644
index 000000000..c681d1945
Binary files /dev/null and b/models/ammocrates/ammo_4x4x1.sw.vtx differ
diff --git a/models/ammocrates/ammo_4x4x1.vvd b/models/ammocrates/ammo_4x4x1.vvd
new file mode 100644
index 000000000..66f882a13
Binary files /dev/null and b/models/ammocrates/ammo_4x4x1.vvd differ
diff --git a/models/ammocrates/ammo_4x6x6.dx80.vtx b/models/ammocrates/ammo_4x6x6.dx80.vtx
new file mode 100644
index 000000000..4ca154fa8
Binary files /dev/null and b/models/ammocrates/ammo_4x6x6.dx80.vtx differ
diff --git a/models/ammocrates/ammo_4x6x6.dx90.vtx b/models/ammocrates/ammo_4x6x6.dx90.vtx
new file mode 100644
index 000000000..fd75fe790
Binary files /dev/null and b/models/ammocrates/ammo_4x6x6.dx90.vtx differ
diff --git a/models/ammocrates/ammo_4x6x6.mdl b/models/ammocrates/ammo_4x6x6.mdl
new file mode 100644
index 000000000..2c0a271ae
Binary files /dev/null and b/models/ammocrates/ammo_4x6x6.mdl differ
diff --git a/models/ammocrates/ammo_4x6x6.phy b/models/ammocrates/ammo_4x6x6.phy
new file mode 100644
index 000000000..f7e4df97e
Binary files /dev/null and b/models/ammocrates/ammo_4x6x6.phy differ
diff --git a/models/ammocrates/ammo_4x6x6.sw.vtx b/models/ammocrates/ammo_4x6x6.sw.vtx
new file mode 100644
index 000000000..62e0d7ba7
Binary files /dev/null and b/models/ammocrates/ammo_4x6x6.sw.vtx differ
diff --git a/models/ammocrates/ammo_4x6x6.vvd b/models/ammocrates/ammo_4x6x6.vvd
new file mode 100644
index 000000000..571cd16fc
Binary files /dev/null and b/models/ammocrates/ammo_4x6x6.vvd differ
diff --git a/models/ammocrates/ammo_4x6x8.dx80.vtx b/models/ammocrates/ammo_4x6x8.dx80.vtx
new file mode 100644
index 000000000..a8c1b8069
Binary files /dev/null and b/models/ammocrates/ammo_4x6x8.dx80.vtx differ
diff --git a/models/ammocrates/ammo_4x6x8.dx90.vtx b/models/ammocrates/ammo_4x6x8.dx90.vtx
new file mode 100644
index 000000000..a28fcc880
Binary files /dev/null and b/models/ammocrates/ammo_4x6x8.dx90.vtx differ
diff --git a/models/ammocrates/ammo_4x6x8.mdl b/models/ammocrates/ammo_4x6x8.mdl
new file mode 100644
index 000000000..67866b9a8
Binary files /dev/null and b/models/ammocrates/ammo_4x6x8.mdl differ
diff --git a/models/ammocrates/ammo_4x6x8.phy b/models/ammocrates/ammo_4x6x8.phy
new file mode 100644
index 000000000..2675ce8a6
Binary files /dev/null and b/models/ammocrates/ammo_4x6x8.phy differ
diff --git a/models/ammocrates/ammo_4x6x8.sw.vtx b/models/ammocrates/ammo_4x6x8.sw.vtx
new file mode 100644
index 000000000..660b136b7
Binary files /dev/null and b/models/ammocrates/ammo_4x6x8.sw.vtx differ
diff --git a/models/ammocrates/ammo_4x6x8.vvd b/models/ammocrates/ammo_4x6x8.vvd
new file mode 100644
index 000000000..9c0588beb
Binary files /dev/null and b/models/ammocrates/ammo_4x6x8.vvd differ
diff --git a/models/ammocrates/ammo_4x8x8.dx80.vtx b/models/ammocrates/ammo_4x8x8.dx80.vtx
new file mode 100644
index 000000000..092761b44
Binary files /dev/null and b/models/ammocrates/ammo_4x8x8.dx80.vtx differ
diff --git a/models/ammocrates/ammo_4x8x8.dx90.vtx b/models/ammocrates/ammo_4x8x8.dx90.vtx
new file mode 100644
index 000000000..f82b67d29
Binary files /dev/null and b/models/ammocrates/ammo_4x8x8.dx90.vtx differ
diff --git a/models/ammocrates/ammo_4x8x8.mdl b/models/ammocrates/ammo_4x8x8.mdl
new file mode 100644
index 000000000..23d867e85
Binary files /dev/null and b/models/ammocrates/ammo_4x8x8.mdl differ
diff --git a/models/ammocrates/ammo_4x8x8.phy b/models/ammocrates/ammo_4x8x8.phy
new file mode 100644
index 000000000..be839f7d2
Binary files /dev/null and b/models/ammocrates/ammo_4x8x8.phy differ
diff --git a/models/ammocrates/ammo_4x8x8.sw.vtx b/models/ammocrates/ammo_4x8x8.sw.vtx
new file mode 100644
index 000000000..5ee1eb555
Binary files /dev/null and b/models/ammocrates/ammo_4x8x8.sw.vtx differ
diff --git a/models/ammocrates/ammo_4x8x8.vvd b/models/ammocrates/ammo_4x8x8.vvd
new file mode 100644
index 000000000..3607c742e
Binary files /dev/null and b/models/ammocrates/ammo_4x8x8.vvd differ
diff --git a/models/ammocrates/ammocrate_2x3x6.dx80.vtx b/models/ammocrates/ammocrate_2x3x6.dx80.vtx
new file mode 100644
index 000000000..b0786d3c0
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x6.dx80.vtx differ
diff --git a/models/ammocrates/ammocrate_2x3x6.dx90.vtx b/models/ammocrates/ammocrate_2x3x6.dx90.vtx
new file mode 100644
index 000000000..560062ae5
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x6.dx90.vtx differ
diff --git a/models/ammocrates/ammocrate_2x3x6.mdl b/models/ammocrates/ammocrate_2x3x6.mdl
new file mode 100644
index 000000000..d8f70a5c0
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x6.mdl differ
diff --git a/models/ammocrates/ammocrate_2x3x6.phy b/models/ammocrates/ammocrate_2x3x6.phy
new file mode 100644
index 000000000..7f6f24297
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x6.phy differ
diff --git a/models/ammocrates/ammocrate_2x3x6.sw.vtx b/models/ammocrates/ammocrate_2x3x6.sw.vtx
new file mode 100644
index 000000000..062c62d67
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x6.sw.vtx differ
diff --git a/models/ammocrates/ammocrate_2x3x6.vvd b/models/ammocrates/ammocrate_2x3x6.vvd
new file mode 100644
index 000000000..42df10e4b
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x6.vvd differ
diff --git a/models/ammocrates/ammocrate_2x3x8.dx80.vtx b/models/ammocrates/ammocrate_2x3x8.dx80.vtx
new file mode 100644
index 000000000..40d34ee3b
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x8.dx80.vtx differ
diff --git a/models/ammocrates/ammocrate_2x3x8.dx90.vtx b/models/ammocrates/ammocrate_2x3x8.dx90.vtx
new file mode 100644
index 000000000..92220829d
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x8.dx90.vtx differ
diff --git a/models/ammocrates/ammocrate_2x3x8.mdl b/models/ammocrates/ammocrate_2x3x8.mdl
new file mode 100644
index 000000000..cff963580
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x8.mdl differ
diff --git a/models/ammocrates/ammocrate_2x3x8.phy b/models/ammocrates/ammocrate_2x3x8.phy
new file mode 100644
index 000000000..58cff74cc
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x8.phy differ
diff --git a/models/ammocrates/ammocrate_2x3x8.sw.vtx b/models/ammocrates/ammocrate_2x3x8.sw.vtx
new file mode 100644
index 000000000..74c10a6bb
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x8.sw.vtx differ
diff --git a/models/ammocrates/ammocrate_2x3x8.vvd b/models/ammocrates/ammocrate_2x3x8.vvd
new file mode 100644
index 000000000..c7afaf9ec
Binary files /dev/null and b/models/ammocrates/ammocrate_2x3x8.vvd differ
diff --git a/models/autocannon/autocannon_20mm.dx80.vtx b/models/autocannon/autocannon_20mm.dx80.vtx
index 0a34a4056..d1bb61112 100644
Binary files a/models/autocannon/autocannon_20mm.dx80.vtx and b/models/autocannon/autocannon_20mm.dx80.vtx differ
diff --git a/models/autocannon/autocannon_20mm.dx90.vtx b/models/autocannon/autocannon_20mm.dx90.vtx
index 9291ae482..fbef7351c 100644
Binary files a/models/autocannon/autocannon_20mm.dx90.vtx and b/models/autocannon/autocannon_20mm.dx90.vtx differ
diff --git a/models/autocannon/autocannon_20mm.mdl b/models/autocannon/autocannon_20mm.mdl
index f07a39edd..1699df6ee 100644
Binary files a/models/autocannon/autocannon_20mm.mdl and b/models/autocannon/autocannon_20mm.mdl differ
diff --git a/models/autocannon/autocannon_20mm.phy b/models/autocannon/autocannon_20mm.phy
index 09767cc79..ff2f97b82 100644
Binary files a/models/autocannon/autocannon_20mm.phy and b/models/autocannon/autocannon_20mm.phy differ
diff --git a/models/autocannon/autocannon_20mm.sw.vtx b/models/autocannon/autocannon_20mm.sw.vtx
index 032523283..773953410 100644
Binary files a/models/autocannon/autocannon_20mm.sw.vtx and b/models/autocannon/autocannon_20mm.sw.vtx differ
diff --git a/models/autocannon/autocannon_20mm.vvd b/models/autocannon/autocannon_20mm.vvd
index 33adf324f..cb0596ef0 100644
Binary files a/models/autocannon/autocannon_20mm.vvd and b/models/autocannon/autocannon_20mm.vvd differ
diff --git a/models/autocannon/autocannon_20mm_compact.dx80.vtx b/models/autocannon/autocannon_20mm_compact.dx80.vtx
new file mode 100644
index 000000000..44bc568e6
Binary files /dev/null and b/models/autocannon/autocannon_20mm_compact.dx80.vtx differ
diff --git a/models/autocannon/autocannon_20mm_compact.dx90.vtx b/models/autocannon/autocannon_20mm_compact.dx90.vtx
new file mode 100644
index 000000000..688aa88b2
Binary files /dev/null and b/models/autocannon/autocannon_20mm_compact.dx90.vtx differ
diff --git a/models/autocannon/autocannon_20mm_compact.mdl b/models/autocannon/autocannon_20mm_compact.mdl
new file mode 100644
index 000000000..7d71506b3
Binary files /dev/null and b/models/autocannon/autocannon_20mm_compact.mdl differ
diff --git a/models/autocannon/autocannon_20mm_compact.phy b/models/autocannon/autocannon_20mm_compact.phy
new file mode 100644
index 000000000..a6fe0f222
Binary files /dev/null and b/models/autocannon/autocannon_20mm_compact.phy differ
diff --git a/models/autocannon/autocannon_20mm_compact.sw.vtx b/models/autocannon/autocannon_20mm_compact.sw.vtx
new file mode 100644
index 000000000..01fdece51
Binary files /dev/null and b/models/autocannon/autocannon_20mm_compact.sw.vtx differ
diff --git a/models/autocannon/autocannon_20mm_compact.vvd b/models/autocannon/autocannon_20mm_compact.vvd
new file mode 100644
index 000000000..33ea04992
Binary files /dev/null and b/models/autocannon/autocannon_20mm_compact.vvd differ
diff --git a/models/autocannon/autocannon_30mm.dx80.vtx b/models/autocannon/autocannon_30mm.dx80.vtx
index e7f219210..4e20e35fe 100644
Binary files a/models/autocannon/autocannon_30mm.dx80.vtx and b/models/autocannon/autocannon_30mm.dx80.vtx differ
diff --git a/models/autocannon/autocannon_30mm.dx90.vtx b/models/autocannon/autocannon_30mm.dx90.vtx
index 81ce64c45..39f2d5954 100644
Binary files a/models/autocannon/autocannon_30mm.dx90.vtx and b/models/autocannon/autocannon_30mm.dx90.vtx differ
diff --git a/models/autocannon/autocannon_30mm.mdl b/models/autocannon/autocannon_30mm.mdl
index c10807440..4054fc666 100644
Binary files a/models/autocannon/autocannon_30mm.mdl and b/models/autocannon/autocannon_30mm.mdl differ
diff --git a/models/autocannon/autocannon_30mm.phy b/models/autocannon/autocannon_30mm.phy
index e9e1bf879..700698baa 100644
Binary files a/models/autocannon/autocannon_30mm.phy and b/models/autocannon/autocannon_30mm.phy differ
diff --git a/models/autocannon/autocannon_30mm.sw.vtx b/models/autocannon/autocannon_30mm.sw.vtx
index d5477ed29..4e3316089 100644
Binary files a/models/autocannon/autocannon_30mm.sw.vtx and b/models/autocannon/autocannon_30mm.sw.vtx differ
diff --git a/models/autocannon/autocannon_30mm.vvd b/models/autocannon/autocannon_30mm.vvd
index 802301b8e..4a6e826b6 100644
Binary files a/models/autocannon/autocannon_30mm.vvd and b/models/autocannon/autocannon_30mm.vvd differ
diff --git a/models/autocannon/autocannon_30mm_compact.dx80.vtx b/models/autocannon/autocannon_30mm_compact.dx80.vtx
new file mode 100644
index 000000000..f68f31ce5
Binary files /dev/null and b/models/autocannon/autocannon_30mm_compact.dx80.vtx differ
diff --git a/models/autocannon/autocannon_30mm_compact.dx90.vtx b/models/autocannon/autocannon_30mm_compact.dx90.vtx
new file mode 100644
index 000000000..9026d81c4
Binary files /dev/null and b/models/autocannon/autocannon_30mm_compact.dx90.vtx differ
diff --git a/models/autocannon/autocannon_30mm_compact.mdl b/models/autocannon/autocannon_30mm_compact.mdl
new file mode 100644
index 000000000..6c16dd3f6
Binary files /dev/null and b/models/autocannon/autocannon_30mm_compact.mdl differ
diff --git a/models/autocannon/autocannon_30mm_compact.phy b/models/autocannon/autocannon_30mm_compact.phy
new file mode 100644
index 000000000..375eb019e
Binary files /dev/null and b/models/autocannon/autocannon_30mm_compact.phy differ
diff --git a/models/autocannon/autocannon_30mm_compact.sw.vtx b/models/autocannon/autocannon_30mm_compact.sw.vtx
new file mode 100644
index 000000000..fe25eb78c
Binary files /dev/null and b/models/autocannon/autocannon_30mm_compact.sw.vtx differ
diff --git a/models/autocannon/autocannon_30mm_compact.vvd b/models/autocannon/autocannon_30mm_compact.vvd
new file mode 100644
index 000000000..398109b82
Binary files /dev/null and b/models/autocannon/autocannon_30mm_compact.vvd differ
diff --git a/models/autocannon/autocannon_40mm.dx80.vtx b/models/autocannon/autocannon_40mm.dx80.vtx
index 572d372cd..17f460350 100644
Binary files a/models/autocannon/autocannon_40mm.dx80.vtx and b/models/autocannon/autocannon_40mm.dx80.vtx differ
diff --git a/models/autocannon/autocannon_40mm.dx90.vtx b/models/autocannon/autocannon_40mm.dx90.vtx
index d0fba9bdb..98b4c676e 100644
Binary files a/models/autocannon/autocannon_40mm.dx90.vtx and b/models/autocannon/autocannon_40mm.dx90.vtx differ
diff --git a/models/autocannon/autocannon_40mm.mdl b/models/autocannon/autocannon_40mm.mdl
index 5de3927a2..1914dc1c8 100644
Binary files a/models/autocannon/autocannon_40mm.mdl and b/models/autocannon/autocannon_40mm.mdl differ
diff --git a/models/autocannon/autocannon_40mm.phy b/models/autocannon/autocannon_40mm.phy
index 38cecf63c..fa022fae5 100644
Binary files a/models/autocannon/autocannon_40mm.phy and b/models/autocannon/autocannon_40mm.phy differ
diff --git a/models/autocannon/autocannon_40mm.sw.vtx b/models/autocannon/autocannon_40mm.sw.vtx
index 40d538843..e8710a656 100644
Binary files a/models/autocannon/autocannon_40mm.sw.vtx and b/models/autocannon/autocannon_40mm.sw.vtx differ
diff --git a/models/autocannon/autocannon_40mm.vvd b/models/autocannon/autocannon_40mm.vvd
index e3913d279..c9f9a3f1f 100644
Binary files a/models/autocannon/autocannon_40mm.vvd and b/models/autocannon/autocannon_40mm.vvd differ
diff --git a/models/autocannon/autocannon_40mm_compact.dx80.vtx b/models/autocannon/autocannon_40mm_compact.dx80.vtx
new file mode 100644
index 000000000..1fbec9b35
Binary files /dev/null and b/models/autocannon/autocannon_40mm_compact.dx80.vtx differ
diff --git a/models/autocannon/autocannon_40mm_compact.dx90.vtx b/models/autocannon/autocannon_40mm_compact.dx90.vtx
new file mode 100644
index 000000000..0814cde3f
Binary files /dev/null and b/models/autocannon/autocannon_40mm_compact.dx90.vtx differ
diff --git a/models/autocannon/autocannon_40mm_compact.mdl b/models/autocannon/autocannon_40mm_compact.mdl
new file mode 100644
index 000000000..35cb3a5c4
Binary files /dev/null and b/models/autocannon/autocannon_40mm_compact.mdl differ
diff --git a/models/autocannon/autocannon_40mm_compact.phy b/models/autocannon/autocannon_40mm_compact.phy
new file mode 100644
index 000000000..cc0b1c53c
Binary files /dev/null and b/models/autocannon/autocannon_40mm_compact.phy differ
diff --git a/models/autocannon/autocannon_40mm_compact.sw.vtx b/models/autocannon/autocannon_40mm_compact.sw.vtx
new file mode 100644
index 000000000..e29e19fba
Binary files /dev/null and b/models/autocannon/autocannon_40mm_compact.sw.vtx differ
diff --git a/models/autocannon/autocannon_40mm_compact.vvd b/models/autocannon/autocannon_40mm_compact.vvd
new file mode 100644
index 000000000..055fded5d
Binary files /dev/null and b/models/autocannon/autocannon_40mm_compact.vvd differ
diff --git a/models/autocannon/autocannon_50mm.dx80.vtx b/models/autocannon/autocannon_50mm.dx80.vtx
index 826d569f0..3adacb88d 100644
Binary files a/models/autocannon/autocannon_50mm.dx80.vtx and b/models/autocannon/autocannon_50mm.dx80.vtx differ
diff --git a/models/autocannon/autocannon_50mm.dx90.vtx b/models/autocannon/autocannon_50mm.dx90.vtx
index 04acaf257..0f31be9d7 100644
Binary files a/models/autocannon/autocannon_50mm.dx90.vtx and b/models/autocannon/autocannon_50mm.dx90.vtx differ
diff --git a/models/autocannon/autocannon_50mm.mdl b/models/autocannon/autocannon_50mm.mdl
index 9ce8cc3d5..5a06855c2 100644
Binary files a/models/autocannon/autocannon_50mm.mdl and b/models/autocannon/autocannon_50mm.mdl differ
diff --git a/models/autocannon/autocannon_50mm.phy b/models/autocannon/autocannon_50mm.phy
index 33c21d583..21691ea68 100644
Binary files a/models/autocannon/autocannon_50mm.phy and b/models/autocannon/autocannon_50mm.phy differ
diff --git a/models/autocannon/autocannon_50mm.sw.vtx b/models/autocannon/autocannon_50mm.sw.vtx
index b67c53f7a..925556c6c 100644
Binary files a/models/autocannon/autocannon_50mm.sw.vtx and b/models/autocannon/autocannon_50mm.sw.vtx differ
diff --git a/models/autocannon/autocannon_50mm.vvd b/models/autocannon/autocannon_50mm.vvd
index a65a8635b..4a1e9dd55 100644
Binary files a/models/autocannon/autocannon_50mm.vvd and b/models/autocannon/autocannon_50mm.vvd differ
diff --git a/models/autocannon/semiautocannon_25mm.dx80.vtx b/models/autocannon/semiautocannon_25mm.dx80.vtx
new file mode 100644
index 000000000..670d392d6
Binary files /dev/null and b/models/autocannon/semiautocannon_25mm.dx80.vtx differ
diff --git a/models/autocannon/semiautocannon_25mm.dx90.vtx b/models/autocannon/semiautocannon_25mm.dx90.vtx
new file mode 100644
index 000000000..cdb5ab925
Binary files /dev/null and b/models/autocannon/semiautocannon_25mm.dx90.vtx differ
diff --git a/models/autocannon/semiautocannon_25mm.mdl b/models/autocannon/semiautocannon_25mm.mdl
new file mode 100644
index 000000000..2c0ce0dfa
Binary files /dev/null and b/models/autocannon/semiautocannon_25mm.mdl differ
diff --git a/models/autocannon/semiautocannon_25mm.phy b/models/autocannon/semiautocannon_25mm.phy
new file mode 100644
index 000000000..25ee92a08
Binary files /dev/null and b/models/autocannon/semiautocannon_25mm.phy differ
diff --git a/models/autocannon/semiautocannon_25mm.sw.vtx b/models/autocannon/semiautocannon_25mm.sw.vtx
new file mode 100644
index 000000000..9a460c128
Binary files /dev/null and b/models/autocannon/semiautocannon_25mm.sw.vtx differ
diff --git a/models/autocannon/semiautocannon_25mm.vvd b/models/autocannon/semiautocannon_25mm.vvd
new file mode 100644
index 000000000..7440c9c42
Binary files /dev/null and b/models/autocannon/semiautocannon_25mm.vvd differ
diff --git a/models/autocannon/semiautocannon_37mm.dx80.vtx b/models/autocannon/semiautocannon_37mm.dx80.vtx
new file mode 100644
index 000000000..b9d038e80
Binary files /dev/null and b/models/autocannon/semiautocannon_37mm.dx80.vtx differ
diff --git a/models/autocannon/semiautocannon_37mm.dx90.vtx b/models/autocannon/semiautocannon_37mm.dx90.vtx
new file mode 100644
index 000000000..20f9e77c5
Binary files /dev/null and b/models/autocannon/semiautocannon_37mm.dx90.vtx differ
diff --git a/models/autocannon/semiautocannon_37mm.mdl b/models/autocannon/semiautocannon_37mm.mdl
new file mode 100644
index 000000000..f08c106b7
Binary files /dev/null and b/models/autocannon/semiautocannon_37mm.mdl differ
diff --git a/models/autocannon/semiautocannon_37mm.phy b/models/autocannon/semiautocannon_37mm.phy
new file mode 100644
index 000000000..07ee9aadf
Binary files /dev/null and b/models/autocannon/semiautocannon_37mm.phy differ
diff --git a/models/autocannon/semiautocannon_37mm.sw.vtx b/models/autocannon/semiautocannon_37mm.sw.vtx
new file mode 100644
index 000000000..16747fd6d
Binary files /dev/null and b/models/autocannon/semiautocannon_37mm.sw.vtx differ
diff --git a/models/autocannon/semiautocannon_37mm.vvd b/models/autocannon/semiautocannon_37mm.vvd
new file mode 100644
index 000000000..5aa88dca4
Binary files /dev/null and b/models/autocannon/semiautocannon_37mm.vvd differ
diff --git a/models/autocannon/semiautocannon_45mm.dx80.vtx b/models/autocannon/semiautocannon_45mm.dx80.vtx
new file mode 100644
index 000000000..8d639fbc2
Binary files /dev/null and b/models/autocannon/semiautocannon_45mm.dx80.vtx differ
diff --git a/models/autocannon/semiautocannon_45mm.dx90.vtx b/models/autocannon/semiautocannon_45mm.dx90.vtx
new file mode 100644
index 000000000..e0b0556da
Binary files /dev/null and b/models/autocannon/semiautocannon_45mm.dx90.vtx differ
diff --git a/models/autocannon/semiautocannon_45mm.mdl b/models/autocannon/semiautocannon_45mm.mdl
new file mode 100644
index 000000000..fdb662de9
Binary files /dev/null and b/models/autocannon/semiautocannon_45mm.mdl differ
diff --git a/models/autocannon/semiautocannon_45mm.phy b/models/autocannon/semiautocannon_45mm.phy
new file mode 100644
index 000000000..5a4251974
Binary files /dev/null and b/models/autocannon/semiautocannon_45mm.phy differ
diff --git a/models/autocannon/semiautocannon_45mm.sw.vtx b/models/autocannon/semiautocannon_45mm.sw.vtx
new file mode 100644
index 000000000..f038022c2
Binary files /dev/null and b/models/autocannon/semiautocannon_45mm.sw.vtx differ
diff --git a/models/autocannon/semiautocannon_45mm.vvd b/models/autocannon/semiautocannon_45mm.vvd
new file mode 100644
index 000000000..9c7555528
Binary files /dev/null and b/models/autocannon/semiautocannon_45mm.vvd differ
diff --git a/models/autocannon/semiautocannon_57mm.dx80.vtx b/models/autocannon/semiautocannon_57mm.dx80.vtx
new file mode 100644
index 000000000..05bd7397a
Binary files /dev/null and b/models/autocannon/semiautocannon_57mm.dx80.vtx differ
diff --git a/models/autocannon/semiautocannon_57mm.dx90.vtx b/models/autocannon/semiautocannon_57mm.dx90.vtx
new file mode 100644
index 000000000..8f679c862
Binary files /dev/null and b/models/autocannon/semiautocannon_57mm.dx90.vtx differ
diff --git a/models/autocannon/semiautocannon_57mm.mdl b/models/autocannon/semiautocannon_57mm.mdl
new file mode 100644
index 000000000..4202424c7
Binary files /dev/null and b/models/autocannon/semiautocannon_57mm.mdl differ
diff --git a/models/autocannon/semiautocannon_57mm.phy b/models/autocannon/semiautocannon_57mm.phy
new file mode 100644
index 000000000..50d7a9715
Binary files /dev/null and b/models/autocannon/semiautocannon_57mm.phy differ
diff --git a/models/autocannon/semiautocannon_57mm.sw.vtx b/models/autocannon/semiautocannon_57mm.sw.vtx
new file mode 100644
index 000000000..929b03b8a
Binary files /dev/null and b/models/autocannon/semiautocannon_57mm.sw.vtx differ
diff --git a/models/autocannon/semiautocannon_57mm.vvd b/models/autocannon/semiautocannon_57mm.vvd
new file mode 100644
index 000000000..c8a826b54
Binary files /dev/null and b/models/autocannon/semiautocannon_57mm.vvd differ
diff --git a/models/autocannon/semiautocannon_76mm.dx80.vtx b/models/autocannon/semiautocannon_76mm.dx80.vtx
new file mode 100644
index 000000000..82eaa7a05
Binary files /dev/null and b/models/autocannon/semiautocannon_76mm.dx80.vtx differ
diff --git a/models/autocannon/semiautocannon_76mm.dx90.vtx b/models/autocannon/semiautocannon_76mm.dx90.vtx
new file mode 100644
index 000000000..53faf06b4
Binary files /dev/null and b/models/autocannon/semiautocannon_76mm.dx90.vtx differ
diff --git a/models/autocannon/semiautocannon_76mm.mdl b/models/autocannon/semiautocannon_76mm.mdl
new file mode 100644
index 000000000..ee4084ca9
Binary files /dev/null and b/models/autocannon/semiautocannon_76mm.mdl differ
diff --git a/models/autocannon/semiautocannon_76mm.phy b/models/autocannon/semiautocannon_76mm.phy
new file mode 100644
index 000000000..9ce4446d9
Binary files /dev/null and b/models/autocannon/semiautocannon_76mm.phy differ
diff --git a/models/autocannon/semiautocannon_76mm.sw.vtx b/models/autocannon/semiautocannon_76mm.sw.vtx
new file mode 100644
index 000000000..bdbd969e2
Binary files /dev/null and b/models/autocannon/semiautocannon_76mm.sw.vtx differ
diff --git a/models/autocannon/semiautocannon_76mm.vvd b/models/autocannon/semiautocannon_76mm.vvd
new file mode 100644
index 000000000..3a8488648
Binary files /dev/null and b/models/autocannon/semiautocannon_76mm.vvd differ
diff --git a/models/engines/1cylb.dx80.vtx b/models/engines/1cylb.dx80.vtx
deleted file mode 100644
index fbbbb9ab2..000000000
Binary files a/models/engines/1cylb.dx80.vtx and /dev/null differ
diff --git a/models/engines/1cylb.dx90.vtx b/models/engines/1cylb.dx90.vtx
deleted file mode 100644
index b305c97d2..000000000
Binary files a/models/engines/1cylb.dx90.vtx and /dev/null differ
diff --git a/models/engines/1cylb.mdl b/models/engines/1cylb.mdl
deleted file mode 100644
index 6da7d6ed0..000000000
Binary files a/models/engines/1cylb.mdl and /dev/null differ
diff --git a/models/engines/1cylb.phy b/models/engines/1cylb.phy
deleted file mode 100644
index aaa8d01f2..000000000
Binary files a/models/engines/1cylb.phy and /dev/null differ
diff --git a/models/engines/1cylb.sw.vtx b/models/engines/1cylb.sw.vtx
deleted file mode 100644
index b046d181c..000000000
Binary files a/models/engines/1cylb.sw.vtx and /dev/null differ
diff --git a/models/engines/1cylb.vvd b/models/engines/1cylb.vvd
deleted file mode 100644
index 486ea9b52..000000000
Binary files a/models/engines/1cylb.vvd and /dev/null differ
diff --git a/models/engines/1cylbig.dx80.vtx b/models/engines/1cylbig.dx80.vtx
new file mode 100644
index 000000000..751ce19b1
Binary files /dev/null and b/models/engines/1cylbig.dx80.vtx differ
diff --git a/models/engines/1cylbig.dx90.vtx b/models/engines/1cylbig.dx90.vtx
new file mode 100644
index 000000000..74873a812
Binary files /dev/null and b/models/engines/1cylbig.dx90.vtx differ
diff --git a/models/engines/1cylbig.mdl b/models/engines/1cylbig.mdl
new file mode 100644
index 000000000..6d17f5ba0
Binary files /dev/null and b/models/engines/1cylbig.mdl differ
diff --git a/models/engines/1cylbig.phy b/models/engines/1cylbig.phy
new file mode 100644
index 000000000..74a01d96c
Binary files /dev/null and b/models/engines/1cylbig.phy differ
diff --git a/models/engines/1cylbig.sw.vtx b/models/engines/1cylbig.sw.vtx
new file mode 100644
index 000000000..645d7d494
Binary files /dev/null and b/models/engines/1cylbig.sw.vtx differ
diff --git a/models/engines/1cylbig.vvd b/models/engines/1cylbig.vvd
new file mode 100644
index 000000000..46f30f451
Binary files /dev/null and b/models/engines/1cylbig.vvd differ
diff --git a/models/engines/1cylm.dx80.vtx b/models/engines/1cylm.dx80.vtx
deleted file mode 100644
index c46c474b1..000000000
Binary files a/models/engines/1cylm.dx80.vtx and /dev/null differ
diff --git a/models/engines/1cylm.dx90.vtx b/models/engines/1cylm.dx90.vtx
deleted file mode 100644
index 265f9dd51..000000000
Binary files a/models/engines/1cylm.dx90.vtx and /dev/null differ
diff --git a/models/engines/1cylm.mdl b/models/engines/1cylm.mdl
deleted file mode 100644
index e74bd3538..000000000
Binary files a/models/engines/1cylm.mdl and /dev/null differ
diff --git a/models/engines/1cylm.phy b/models/engines/1cylm.phy
deleted file mode 100644
index 41350e01d..000000000
Binary files a/models/engines/1cylm.phy and /dev/null differ
diff --git a/models/engines/1cylm.sw.vtx b/models/engines/1cylm.sw.vtx
deleted file mode 100644
index 56fe21b28..000000000
Binary files a/models/engines/1cylm.sw.vtx and /dev/null differ
diff --git a/models/engines/1cylm.vvd b/models/engines/1cylm.vvd
deleted file mode 100644
index 28616b3bb..000000000
Binary files a/models/engines/1cylm.vvd and /dev/null differ
diff --git a/models/engines/1cylmed.dx80.vtx b/models/engines/1cylmed.dx80.vtx
new file mode 100644
index 000000000..64e5467a5
Binary files /dev/null and b/models/engines/1cylmed.dx80.vtx differ
diff --git a/models/engines/1cylmed.dx90.vtx b/models/engines/1cylmed.dx90.vtx
new file mode 100644
index 000000000..aa519c783
Binary files /dev/null and b/models/engines/1cylmed.dx90.vtx differ
diff --git a/models/engines/1cylmed.mdl b/models/engines/1cylmed.mdl
new file mode 100644
index 000000000..f719f1630
Binary files /dev/null and b/models/engines/1cylmed.mdl differ
diff --git a/models/engines/1cylmed.phy b/models/engines/1cylmed.phy
new file mode 100644
index 000000000..ad13b9cdb
Binary files /dev/null and b/models/engines/1cylmed.phy differ
diff --git a/models/engines/1cylmed.sw.vtx b/models/engines/1cylmed.sw.vtx
new file mode 100644
index 000000000..c6e799891
Binary files /dev/null and b/models/engines/1cylmed.sw.vtx differ
diff --git a/models/engines/1cylmed.vvd b/models/engines/1cylmed.vvd
new file mode 100644
index 000000000..89aa9f303
Binary files /dev/null and b/models/engines/1cylmed.vvd differ
diff --git a/models/engines/1cyls.dx80.vtx b/models/engines/1cyls.dx80.vtx
deleted file mode 100644
index aef22e02d..000000000
Binary files a/models/engines/1cyls.dx80.vtx and /dev/null differ
diff --git a/models/engines/1cyls.dx90.vtx b/models/engines/1cyls.dx90.vtx
deleted file mode 100644
index ef8e9d25e..000000000
Binary files a/models/engines/1cyls.dx90.vtx and /dev/null differ
diff --git a/models/engines/1cyls.mdl b/models/engines/1cyls.mdl
deleted file mode 100644
index bfecf0e3f..000000000
Binary files a/models/engines/1cyls.mdl and /dev/null differ
diff --git a/models/engines/1cyls.phy b/models/engines/1cyls.phy
deleted file mode 100644
index 87af5e492..000000000
Binary files a/models/engines/1cyls.phy and /dev/null differ
diff --git a/models/engines/1cyls.sw.vtx b/models/engines/1cyls.sw.vtx
deleted file mode 100644
index 816b124de..000000000
Binary files a/models/engines/1cyls.sw.vtx and /dev/null differ
diff --git a/models/engines/1cyls.vvd b/models/engines/1cyls.vvd
deleted file mode 100644
index 825a727b6..000000000
Binary files a/models/engines/1cyls.vvd and /dev/null differ
diff --git a/models/engines/1cylsml.dx80.vtx b/models/engines/1cylsml.dx80.vtx
new file mode 100644
index 000000000..d83813e04
Binary files /dev/null and b/models/engines/1cylsml.dx80.vtx differ
diff --git a/models/engines/1cylsml.dx90.vtx b/models/engines/1cylsml.dx90.vtx
new file mode 100644
index 000000000..8608f944d
Binary files /dev/null and b/models/engines/1cylsml.dx90.vtx differ
diff --git a/models/engines/1cylsml.mdl b/models/engines/1cylsml.mdl
new file mode 100644
index 000000000..b37552fe8
Binary files /dev/null and b/models/engines/1cylsml.mdl differ
diff --git a/models/engines/1cylsml.phy b/models/engines/1cylsml.phy
new file mode 100644
index 000000000..5041c67e1
Binary files /dev/null and b/models/engines/1cylsml.phy differ
diff --git a/models/engines/1cylsml.sw.vtx b/models/engines/1cylsml.sw.vtx
new file mode 100644
index 000000000..cfaa9f451
Binary files /dev/null and b/models/engines/1cylsml.sw.vtx differ
diff --git a/models/engines/1cylsml.vvd b/models/engines/1cylsml.vvd
new file mode 100644
index 000000000..4bcf1cf12
Binary files /dev/null and b/models/engines/1cylsml.vvd differ
diff --git a/models/engines/emotor-standalone-big.dx80.vtx b/models/engines/emotor-standalone-big.dx80.vtx
new file mode 100644
index 000000000..5f90517db
Binary files /dev/null and b/models/engines/emotor-standalone-big.dx80.vtx differ
diff --git a/models/engines/emotor-standalone-big.dx90.vtx b/models/engines/emotor-standalone-big.dx90.vtx
new file mode 100644
index 000000000..1b15a7958
Binary files /dev/null and b/models/engines/emotor-standalone-big.dx90.vtx differ
diff --git a/models/engines/emotor-standalone-big.mdl b/models/engines/emotor-standalone-big.mdl
new file mode 100644
index 000000000..cb552f8b3
Binary files /dev/null and b/models/engines/emotor-standalone-big.mdl differ
diff --git a/models/engines/emotor-standalone-big.phy b/models/engines/emotor-standalone-big.phy
new file mode 100644
index 000000000..1568120b2
Binary files /dev/null and b/models/engines/emotor-standalone-big.phy differ
diff --git a/models/engines/emotor-standalone-big.sw.vtx b/models/engines/emotor-standalone-big.sw.vtx
new file mode 100644
index 000000000..478da39bf
Binary files /dev/null and b/models/engines/emotor-standalone-big.sw.vtx differ
diff --git a/models/engines/emotor-standalone-big.vvd b/models/engines/emotor-standalone-big.vvd
new file mode 100644
index 000000000..37664d44b
Binary files /dev/null and b/models/engines/emotor-standalone-big.vvd differ
diff --git a/models/engines/emotor-standalone-mid.dx80.vtx b/models/engines/emotor-standalone-mid.dx80.vtx
new file mode 100644
index 000000000..e5624d9f4
Binary files /dev/null and b/models/engines/emotor-standalone-mid.dx80.vtx differ
diff --git a/models/engines/emotor-standalone-mid.dx90.vtx b/models/engines/emotor-standalone-mid.dx90.vtx
new file mode 100644
index 000000000..8e91c93a2
Binary files /dev/null and b/models/engines/emotor-standalone-mid.dx90.vtx differ
diff --git a/models/engines/emotor-standalone-mid.mdl b/models/engines/emotor-standalone-mid.mdl
new file mode 100644
index 000000000..7dc86ad6b
Binary files /dev/null and b/models/engines/emotor-standalone-mid.mdl differ
diff --git a/models/engines/emotor-standalone-mid.phy b/models/engines/emotor-standalone-mid.phy
new file mode 100644
index 000000000..3cf50b171
Binary files /dev/null and b/models/engines/emotor-standalone-mid.phy differ
diff --git a/models/engines/emotor-standalone-mid.sw.vtx b/models/engines/emotor-standalone-mid.sw.vtx
new file mode 100644
index 000000000..6a8aa3c28
Binary files /dev/null and b/models/engines/emotor-standalone-mid.sw.vtx differ
diff --git a/models/engines/emotor-standalone-mid.vvd b/models/engines/emotor-standalone-mid.vvd
new file mode 100644
index 000000000..022029c8e
Binary files /dev/null and b/models/engines/emotor-standalone-mid.vvd differ
diff --git a/models/engines/emotor-standalone-sml.dx80.vtx b/models/engines/emotor-standalone-sml.dx80.vtx
new file mode 100644
index 000000000..44928e8ed
Binary files /dev/null and b/models/engines/emotor-standalone-sml.dx80.vtx differ
diff --git a/models/engines/emotor-standalone-sml.dx90.vtx b/models/engines/emotor-standalone-sml.dx90.vtx
new file mode 100644
index 000000000..5f08cabaf
Binary files /dev/null and b/models/engines/emotor-standalone-sml.dx90.vtx differ
diff --git a/models/engines/emotor-standalone-sml.mdl b/models/engines/emotor-standalone-sml.mdl
new file mode 100644
index 000000000..c696dead5
Binary files /dev/null and b/models/engines/emotor-standalone-sml.mdl differ
diff --git a/models/engines/emotor-standalone-sml.phy b/models/engines/emotor-standalone-sml.phy
new file mode 100644
index 000000000..750236d0f
Binary files /dev/null and b/models/engines/emotor-standalone-sml.phy differ
diff --git a/models/engines/emotor-standalone-sml.sw.vtx b/models/engines/emotor-standalone-sml.sw.vtx
new file mode 100644
index 000000000..b84b90e07
Binary files /dev/null and b/models/engines/emotor-standalone-sml.sw.vtx differ
diff --git a/models/engines/emotor-standalone-sml.vvd b/models/engines/emotor-standalone-sml.vvd
new file mode 100644
index 000000000..80660c517
Binary files /dev/null and b/models/engines/emotor-standalone-sml.vvd differ
diff --git a/models/engines/emotor-standalone-tiny.dx80.vtx b/models/engines/emotor-standalone-tiny.dx80.vtx
new file mode 100644
index 000000000..25013eef3
Binary files /dev/null and b/models/engines/emotor-standalone-tiny.dx80.vtx differ
diff --git a/models/engines/emotor-standalone-tiny.dx90.vtx b/models/engines/emotor-standalone-tiny.dx90.vtx
new file mode 100644
index 000000000..593a5b35b
Binary files /dev/null and b/models/engines/emotor-standalone-tiny.dx90.vtx differ
diff --git a/models/engines/emotor-standalone-tiny.mdl b/models/engines/emotor-standalone-tiny.mdl
new file mode 100644
index 000000000..0c1291d02
Binary files /dev/null and b/models/engines/emotor-standalone-tiny.mdl differ
diff --git a/models/engines/emotor-standalone-tiny.phy b/models/engines/emotor-standalone-tiny.phy
new file mode 100644
index 000000000..cb536a3a2
Binary files /dev/null and b/models/engines/emotor-standalone-tiny.phy differ
diff --git a/models/engines/emotor-standalone-tiny.sw.vtx b/models/engines/emotor-standalone-tiny.sw.vtx
new file mode 100644
index 000000000..b170a437e
Binary files /dev/null and b/models/engines/emotor-standalone-tiny.sw.vtx differ
diff --git a/models/engines/emotor-standalone-tiny.vvd b/models/engines/emotor-standalone-tiny.vvd
new file mode 100644
index 000000000..8273ff2b7
Binary files /dev/null and b/models/engines/emotor-standalone-tiny.vvd differ
diff --git a/models/engines/emotorlarge.dx80.vtx b/models/engines/emotorlarge.dx80.vtx
index cb46aae5f..185f87b47 100644
Binary files a/models/engines/emotorlarge.dx80.vtx and b/models/engines/emotorlarge.dx80.vtx differ
diff --git a/models/engines/emotorlarge.dx90.vtx b/models/engines/emotorlarge.dx90.vtx
index 5d90aab42..84bae241a 100644
Binary files a/models/engines/emotorlarge.dx90.vtx and b/models/engines/emotorlarge.dx90.vtx differ
diff --git a/models/engines/emotorlarge.mdl b/models/engines/emotorlarge.mdl
index d2824289a..e97b7a9dc 100644
Binary files a/models/engines/emotorlarge.mdl and b/models/engines/emotorlarge.mdl differ
diff --git a/models/engines/emotorlarge.phy b/models/engines/emotorlarge.phy
index 9965792af..a4a7057f8 100644
Binary files a/models/engines/emotorlarge.phy and b/models/engines/emotorlarge.phy differ
diff --git a/models/engines/emotorlarge.sw.vtx b/models/engines/emotorlarge.sw.vtx
index 9b66dc9f5..51c22d7da 100644
Binary files a/models/engines/emotorlarge.sw.vtx and b/models/engines/emotorlarge.sw.vtx differ
diff --git a/models/engines/emotorlarge.vvd b/models/engines/emotorlarge.vvd
index fef99ca89..577f1335f 100644
Binary files a/models/engines/emotorlarge.vvd and b/models/engines/emotorlarge.vvd differ
diff --git a/models/engines/emotorlarge2.dx80.vtx b/models/engines/emotorlarge2.dx80.vtx
new file mode 100644
index 000000000..7f6e71f97
Binary files /dev/null and b/models/engines/emotorlarge2.dx80.vtx differ
diff --git a/models/engines/emotorlarge2.dx90.vtx b/models/engines/emotorlarge2.dx90.vtx
new file mode 100644
index 000000000..aef09a77b
Binary files /dev/null and b/models/engines/emotorlarge2.dx90.vtx differ
diff --git a/models/engines/emotorlarge2.mdl b/models/engines/emotorlarge2.mdl
new file mode 100644
index 000000000..4fa5077f8
Binary files /dev/null and b/models/engines/emotorlarge2.mdl differ
diff --git a/models/engines/emotorlarge2.phy b/models/engines/emotorlarge2.phy
new file mode 100644
index 000000000..9ba15aa00
Binary files /dev/null and b/models/engines/emotorlarge2.phy differ
diff --git a/models/engines/emotorlarge2.sw.vtx b/models/engines/emotorlarge2.sw.vtx
new file mode 100644
index 000000000..1e983065f
Binary files /dev/null and b/models/engines/emotorlarge2.sw.vtx differ
diff --git a/models/engines/emotorlarge2.vvd b/models/engines/emotorlarge2.vvd
new file mode 100644
index 000000000..c3308ad0d
Binary files /dev/null and b/models/engines/emotorlarge2.vvd differ
diff --git a/models/engines/emotormed.dx80.vtx b/models/engines/emotormed.dx80.vtx
index c1fc6095e..dea0cbc26 100644
Binary files a/models/engines/emotormed.dx80.vtx and b/models/engines/emotormed.dx80.vtx differ
diff --git a/models/engines/emotormed.dx90.vtx b/models/engines/emotormed.dx90.vtx
index 29691167e..cbe94208e 100644
Binary files a/models/engines/emotormed.dx90.vtx and b/models/engines/emotormed.dx90.vtx differ
diff --git a/models/engines/emotormed.mdl b/models/engines/emotormed.mdl
index 98bdd984b..cb9dda5ee 100644
Binary files a/models/engines/emotormed.mdl and b/models/engines/emotormed.mdl differ
diff --git a/models/engines/emotormed.phy b/models/engines/emotormed.phy
index 0cd6fce2a..e9782d621 100644
Binary files a/models/engines/emotormed.phy and b/models/engines/emotormed.phy differ
diff --git a/models/engines/emotormed.sw.vtx b/models/engines/emotormed.sw.vtx
index f6f638040..4c9b2c2c3 100644
Binary files a/models/engines/emotormed.sw.vtx and b/models/engines/emotormed.sw.vtx differ
diff --git a/models/engines/emotormed.vvd b/models/engines/emotormed.vvd
index 62da96c28..e18bec45b 100644
Binary files a/models/engines/emotormed.vvd and b/models/engines/emotormed.vvd differ
diff --git a/models/engines/emotormed2.dx80.vtx b/models/engines/emotormed2.dx80.vtx
new file mode 100644
index 000000000..649bfe01f
Binary files /dev/null and b/models/engines/emotormed2.dx80.vtx differ
diff --git a/models/engines/emotormed2.dx90.vtx b/models/engines/emotormed2.dx90.vtx
new file mode 100644
index 000000000..2cfbcc82c
Binary files /dev/null and b/models/engines/emotormed2.dx90.vtx differ
diff --git a/models/engines/emotormed2.mdl b/models/engines/emotormed2.mdl
new file mode 100644
index 000000000..e8cc8b541
Binary files /dev/null and b/models/engines/emotormed2.mdl differ
diff --git a/models/engines/emotormed2.phy b/models/engines/emotormed2.phy
new file mode 100644
index 000000000..9a0b31bb4
Binary files /dev/null and b/models/engines/emotormed2.phy differ
diff --git a/models/engines/emotormed2.sw.vtx b/models/engines/emotormed2.sw.vtx
new file mode 100644
index 000000000..6e856d64c
Binary files /dev/null and b/models/engines/emotormed2.sw.vtx differ
diff --git a/models/engines/emotormed2.vvd b/models/engines/emotormed2.vvd
new file mode 100644
index 000000000..22f4d29cd
Binary files /dev/null and b/models/engines/emotormed2.vvd differ
diff --git a/models/engines/emotorsmall.dx80.vtx b/models/engines/emotorsmall.dx80.vtx
index 195a3d64e..8bdaa7f4b 100644
Binary files a/models/engines/emotorsmall.dx80.vtx and b/models/engines/emotorsmall.dx80.vtx differ
diff --git a/models/engines/emotorsmall.dx90.vtx b/models/engines/emotorsmall.dx90.vtx
index 7db05146e..8cbd4b286 100644
Binary files a/models/engines/emotorsmall.dx90.vtx and b/models/engines/emotorsmall.dx90.vtx differ
diff --git a/models/engines/emotorsmall.mdl b/models/engines/emotorsmall.mdl
index cf1e3d0bb..a3af18652 100644
Binary files a/models/engines/emotorsmall.mdl and b/models/engines/emotorsmall.mdl differ
diff --git a/models/engines/emotorsmall.phy b/models/engines/emotorsmall.phy
index c90fb27a8..0c471d1b3 100644
Binary files a/models/engines/emotorsmall.phy and b/models/engines/emotorsmall.phy differ
diff --git a/models/engines/emotorsmall.sw.vtx b/models/engines/emotorsmall.sw.vtx
index 19a5bc05e..2acee4bc9 100644
Binary files a/models/engines/emotorsmall.sw.vtx and b/models/engines/emotorsmall.sw.vtx differ
diff --git a/models/engines/emotorsmall.vvd b/models/engines/emotorsmall.vvd
index 4f7b0f31f..52d49e497 100644
Binary files a/models/engines/emotorsmall.vvd and b/models/engines/emotorsmall.vvd differ
diff --git a/models/engines/emotorsmall2.dx80.vtx b/models/engines/emotorsmall2.dx80.vtx
new file mode 100644
index 000000000..c7372fdec
Binary files /dev/null and b/models/engines/emotorsmall2.dx80.vtx differ
diff --git a/models/engines/emotorsmall2.dx90.vtx b/models/engines/emotorsmall2.dx90.vtx
new file mode 100644
index 000000000..32a78af27
Binary files /dev/null and b/models/engines/emotorsmall2.dx90.vtx differ
diff --git a/models/engines/emotorsmall2.mdl b/models/engines/emotorsmall2.mdl
new file mode 100644
index 000000000..451ebc4d3
Binary files /dev/null and b/models/engines/emotorsmall2.mdl differ
diff --git a/models/engines/emotorsmall2.phy b/models/engines/emotorsmall2.phy
new file mode 100644
index 000000000..578124e52
Binary files /dev/null and b/models/engines/emotorsmall2.phy differ
diff --git a/models/engines/emotorsmall2.sw.vtx b/models/engines/emotorsmall2.sw.vtx
new file mode 100644
index 000000000..e3e33e032
Binary files /dev/null and b/models/engines/emotorsmall2.sw.vtx differ
diff --git a/models/engines/emotorsmall2.vvd b/models/engines/emotorsmall2.vvd
new file mode 100644
index 000000000..9e3a20e35
Binary files /dev/null and b/models/engines/emotorsmall2.vvd differ
diff --git a/models/engines/flywheelclutchb.dx80.vtx b/models/engines/flywheelclutchb.dx80.vtx
new file mode 100644
index 000000000..6c00a58df
Binary files /dev/null and b/models/engines/flywheelclutchb.dx80.vtx differ
diff --git a/models/engines/flywheelclutchb.dx90.vtx b/models/engines/flywheelclutchb.dx90.vtx
new file mode 100644
index 000000000..087fae196
Binary files /dev/null and b/models/engines/flywheelclutchb.dx90.vtx differ
diff --git a/models/engines/flywheelclutchb.mdl b/models/engines/flywheelclutchb.mdl
new file mode 100644
index 000000000..870ed7bf0
Binary files /dev/null and b/models/engines/flywheelclutchb.mdl differ
diff --git a/models/engines/flywheelclutchb.phy b/models/engines/flywheelclutchb.phy
new file mode 100644
index 000000000..2e4b151c6
Binary files /dev/null and b/models/engines/flywheelclutchb.phy differ
diff --git a/models/engines/flywheelclutchb.sw.vtx b/models/engines/flywheelclutchb.sw.vtx
new file mode 100644
index 000000000..a758b9630
Binary files /dev/null and b/models/engines/flywheelclutchb.sw.vtx differ
diff --git a/models/engines/flywheelclutchb.vvd b/models/engines/flywheelclutchb.vvd
new file mode 100644
index 000000000..ff38fa16b
Binary files /dev/null and b/models/engines/flywheelclutchb.vvd differ
diff --git a/models/engines/flywheelclutchm.dx80.vtx b/models/engines/flywheelclutchm.dx80.vtx
new file mode 100644
index 000000000..b7e9eec65
Binary files /dev/null and b/models/engines/flywheelclutchm.dx80.vtx differ
diff --git a/models/engines/flywheelclutchm.dx90.vtx b/models/engines/flywheelclutchm.dx90.vtx
new file mode 100644
index 000000000..d4df97e3c
Binary files /dev/null and b/models/engines/flywheelclutchm.dx90.vtx differ
diff --git a/models/engines/flywheelclutchm.mdl b/models/engines/flywheelclutchm.mdl
new file mode 100644
index 000000000..2a4a2391c
Binary files /dev/null and b/models/engines/flywheelclutchm.mdl differ
diff --git a/models/engines/flywheelclutchm.phy b/models/engines/flywheelclutchm.phy
new file mode 100644
index 000000000..5a73b3a11
Binary files /dev/null and b/models/engines/flywheelclutchm.phy differ
diff --git a/models/engines/flywheelclutchm.sw.vtx b/models/engines/flywheelclutchm.sw.vtx
new file mode 100644
index 000000000..3d811b19e
Binary files /dev/null and b/models/engines/flywheelclutchm.sw.vtx differ
diff --git a/models/engines/flywheelclutchm.vvd b/models/engines/flywheelclutchm.vvd
new file mode 100644
index 000000000..adf2704e7
Binary files /dev/null and b/models/engines/flywheelclutchm.vvd differ
diff --git a/models/engines/flywheelclutchs.dx80.vtx b/models/engines/flywheelclutchs.dx80.vtx
new file mode 100644
index 000000000..75628b0ea
Binary files /dev/null and b/models/engines/flywheelclutchs.dx80.vtx differ
diff --git a/models/engines/flywheelclutchs.dx90.vtx b/models/engines/flywheelclutchs.dx90.vtx
new file mode 100644
index 000000000..5d233d853
Binary files /dev/null and b/models/engines/flywheelclutchs.dx90.vtx differ
diff --git a/models/engines/flywheelclutchs.mdl b/models/engines/flywheelclutchs.mdl
new file mode 100644
index 000000000..80d3eae92
Binary files /dev/null and b/models/engines/flywheelclutchs.mdl differ
diff --git a/models/engines/flywheelclutchs.phy b/models/engines/flywheelclutchs.phy
new file mode 100644
index 000000000..b5d1b239f
Binary files /dev/null and b/models/engines/flywheelclutchs.phy differ
diff --git a/models/engines/flywheelclutchs.sw.vtx b/models/engines/flywheelclutchs.sw.vtx
new file mode 100644
index 000000000..6d7023999
Binary files /dev/null and b/models/engines/flywheelclutchs.sw.vtx differ
diff --git a/models/engines/flywheelclutchs.vvd b/models/engines/flywheelclutchs.vvd
new file mode 100644
index 000000000..bfb6ee19e
Binary files /dev/null and b/models/engines/flywheelclutchs.vvd differ
diff --git a/models/engines/flywheelclutcht.dx80.vtx b/models/engines/flywheelclutcht.dx80.vtx
new file mode 100644
index 000000000..dcb04fb24
Binary files /dev/null and b/models/engines/flywheelclutcht.dx80.vtx differ
diff --git a/models/engines/flywheelclutcht.dx90.vtx b/models/engines/flywheelclutcht.dx90.vtx
new file mode 100644
index 000000000..03e48f9f2
Binary files /dev/null and b/models/engines/flywheelclutcht.dx90.vtx differ
diff --git a/models/engines/flywheelclutcht.mdl b/models/engines/flywheelclutcht.mdl
new file mode 100644
index 000000000..a1cbac78e
Binary files /dev/null and b/models/engines/flywheelclutcht.mdl differ
diff --git a/models/engines/flywheelclutcht.phy b/models/engines/flywheelclutcht.phy
new file mode 100644
index 000000000..f20399082
Binary files /dev/null and b/models/engines/flywheelclutcht.phy differ
diff --git a/models/engines/flywheelclutcht.sw.vtx b/models/engines/flywheelclutcht.sw.vtx
new file mode 100644
index 000000000..20a5c8c30
Binary files /dev/null and b/models/engines/flywheelclutcht.sw.vtx differ
diff --git a/models/engines/flywheelclutcht.vvd b/models/engines/flywheelclutcht.vvd
new file mode 100644
index 000000000..e2e3e742f
Binary files /dev/null and b/models/engines/flywheelclutcht.vvd differ
diff --git a/models/engines/inline2b.dx80.vtx b/models/engines/inline2b.dx80.vtx
new file mode 100644
index 000000000..8a7e61441
Binary files /dev/null and b/models/engines/inline2b.dx80.vtx differ
diff --git a/models/engines/inline2b.dx90.vtx b/models/engines/inline2b.dx90.vtx
new file mode 100644
index 000000000..a249cdba9
Binary files /dev/null and b/models/engines/inline2b.dx90.vtx differ
diff --git a/models/engines/inline2b.mdl b/models/engines/inline2b.mdl
new file mode 100644
index 000000000..0c35b5323
Binary files /dev/null and b/models/engines/inline2b.mdl differ
diff --git a/models/engines/inline2b.phy b/models/engines/inline2b.phy
new file mode 100644
index 000000000..3c13bc0be
Binary files /dev/null and b/models/engines/inline2b.phy differ
diff --git a/models/engines/inline2b.sw.vtx b/models/engines/inline2b.sw.vtx
new file mode 100644
index 000000000..a04f7ea9d
Binary files /dev/null and b/models/engines/inline2b.sw.vtx differ
diff --git a/models/engines/inline2b.vvd b/models/engines/inline2b.vvd
new file mode 100644
index 000000000..35d4d6bde
Binary files /dev/null and b/models/engines/inline2b.vvd differ
diff --git a/models/engines/inline2m.dx80.vtx b/models/engines/inline2m.dx80.vtx
new file mode 100644
index 000000000..cb7fd3ce4
Binary files /dev/null and b/models/engines/inline2m.dx80.vtx differ
diff --git a/models/engines/inline2m.dx90.vtx b/models/engines/inline2m.dx90.vtx
new file mode 100644
index 000000000..a8a7906f0
Binary files /dev/null and b/models/engines/inline2m.dx90.vtx differ
diff --git a/models/engines/inline2m.mdl b/models/engines/inline2m.mdl
new file mode 100644
index 000000000..088b70b4a
Binary files /dev/null and b/models/engines/inline2m.mdl differ
diff --git a/models/engines/inline2m.phy b/models/engines/inline2m.phy
new file mode 100644
index 000000000..ee2bb70f0
Binary files /dev/null and b/models/engines/inline2m.phy differ
diff --git a/models/engines/inline2m.sw.vtx b/models/engines/inline2m.sw.vtx
new file mode 100644
index 000000000..a61479387
Binary files /dev/null and b/models/engines/inline2m.sw.vtx differ
diff --git a/models/engines/inline2m.vvd b/models/engines/inline2m.vvd
new file mode 100644
index 000000000..97b7f1436
Binary files /dev/null and b/models/engines/inline2m.vvd differ
diff --git a/models/engines/inline2s.dx80.vtx b/models/engines/inline2s.dx80.vtx
new file mode 100644
index 000000000..5fab875e5
Binary files /dev/null and b/models/engines/inline2s.dx80.vtx differ
diff --git a/models/engines/inline2s.dx90.vtx b/models/engines/inline2s.dx90.vtx
new file mode 100644
index 000000000..17ff30064
Binary files /dev/null and b/models/engines/inline2s.dx90.vtx differ
diff --git a/models/engines/inline2s.mdl b/models/engines/inline2s.mdl
new file mode 100644
index 000000000..fe7999935
Binary files /dev/null and b/models/engines/inline2s.mdl differ
diff --git a/models/engines/inline2s.phy b/models/engines/inline2s.phy
new file mode 100644
index 000000000..67655f68a
Binary files /dev/null and b/models/engines/inline2s.phy differ
diff --git a/models/engines/inline2s.sw.vtx b/models/engines/inline2s.sw.vtx
new file mode 100644
index 000000000..02893be4d
Binary files /dev/null and b/models/engines/inline2s.sw.vtx differ
diff --git a/models/engines/inline2s.vvd b/models/engines/inline2s.vvd
new file mode 100644
index 000000000..ded3c2bdb
Binary files /dev/null and b/models/engines/inline2s.vvd differ
diff --git a/models/engines/inline3b.dx80.vtx b/models/engines/inline3b.dx80.vtx
new file mode 100644
index 000000000..868376d2a
Binary files /dev/null and b/models/engines/inline3b.dx80.vtx differ
diff --git a/models/engines/inline3b.dx90.vtx b/models/engines/inline3b.dx90.vtx
new file mode 100644
index 000000000..c6d44d2c9
Binary files /dev/null and b/models/engines/inline3b.dx90.vtx differ
diff --git a/models/engines/inline3b.mdl b/models/engines/inline3b.mdl
new file mode 100644
index 000000000..c2a73e043
Binary files /dev/null and b/models/engines/inline3b.mdl differ
diff --git a/models/engines/inline3b.phy b/models/engines/inline3b.phy
new file mode 100644
index 000000000..49db8c0f1
Binary files /dev/null and b/models/engines/inline3b.phy differ
diff --git a/models/engines/inline3b.sw.vtx b/models/engines/inline3b.sw.vtx
new file mode 100644
index 000000000..8f038dd4d
Binary files /dev/null and b/models/engines/inline3b.sw.vtx differ
diff --git a/models/engines/inline3b.vvd b/models/engines/inline3b.vvd
new file mode 100644
index 000000000..91d66e071
Binary files /dev/null and b/models/engines/inline3b.vvd differ
diff --git a/models/engines/inline3m.dx80.vtx b/models/engines/inline3m.dx80.vtx
new file mode 100644
index 000000000..a92ec3b96
Binary files /dev/null and b/models/engines/inline3m.dx80.vtx differ
diff --git a/models/engines/inline3m.dx90.vtx b/models/engines/inline3m.dx90.vtx
new file mode 100644
index 000000000..37cc18d0b
Binary files /dev/null and b/models/engines/inline3m.dx90.vtx differ
diff --git a/models/engines/inline3m.mdl b/models/engines/inline3m.mdl
new file mode 100644
index 000000000..38e44c667
Binary files /dev/null and b/models/engines/inline3m.mdl differ
diff --git a/models/engines/inline3m.phy b/models/engines/inline3m.phy
new file mode 100644
index 000000000..6757497f5
Binary files /dev/null and b/models/engines/inline3m.phy differ
diff --git a/models/engines/inline3m.sw.vtx b/models/engines/inline3m.sw.vtx
new file mode 100644
index 000000000..60a71f5ff
Binary files /dev/null and b/models/engines/inline3m.sw.vtx differ
diff --git a/models/engines/inline3m.vvd b/models/engines/inline3m.vvd
new file mode 100644
index 000000000..6eaebda1f
Binary files /dev/null and b/models/engines/inline3m.vvd differ
diff --git a/models/engines/inline3s.dx80.vtx b/models/engines/inline3s.dx80.vtx
new file mode 100644
index 000000000..d39ac6a02
Binary files /dev/null and b/models/engines/inline3s.dx80.vtx differ
diff --git a/models/engines/inline3s.dx90.vtx b/models/engines/inline3s.dx90.vtx
new file mode 100644
index 000000000..2e906fc83
Binary files /dev/null and b/models/engines/inline3s.dx90.vtx differ
diff --git a/models/engines/inline3s.mdl b/models/engines/inline3s.mdl
new file mode 100644
index 000000000..5eee9a33b
Binary files /dev/null and b/models/engines/inline3s.mdl differ
diff --git a/models/engines/inline3s.phy b/models/engines/inline3s.phy
new file mode 100644
index 000000000..e77f985f1
Binary files /dev/null and b/models/engines/inline3s.phy differ
diff --git a/models/engines/inline3s.sw.vtx b/models/engines/inline3s.sw.vtx
new file mode 100644
index 000000000..3c99124c4
Binary files /dev/null and b/models/engines/inline3s.sw.vtx differ
diff --git a/models/engines/inline3s.vvd b/models/engines/inline3s.vvd
new file mode 100644
index 000000000..73ef3f58d
Binary files /dev/null and b/models/engines/inline3s.vvd differ
diff --git a/models/engines/inline4l.dx80.vtx b/models/engines/inline4l.dx80.vtx
index 1cc2ad1eb..6251f7877 100644
Binary files a/models/engines/inline4l.dx80.vtx and b/models/engines/inline4l.dx80.vtx differ
diff --git a/models/engines/inline4l.dx90.vtx b/models/engines/inline4l.dx90.vtx
index 968d9805b..e982bc8b1 100644
Binary files a/models/engines/inline4l.dx90.vtx and b/models/engines/inline4l.dx90.vtx differ
diff --git a/models/engines/inline4l.mdl b/models/engines/inline4l.mdl
index 6e5d53792..3e2380816 100644
Binary files a/models/engines/inline4l.mdl and b/models/engines/inline4l.mdl differ
diff --git a/models/engines/inline4l.phy b/models/engines/inline4l.phy
index 483ce9d4d..f46f90fec 100644
Binary files a/models/engines/inline4l.phy and b/models/engines/inline4l.phy differ
diff --git a/models/engines/inline4l.sw.vtx b/models/engines/inline4l.sw.vtx
index 77cb681f5..f3308a7d4 100644
Binary files a/models/engines/inline4l.sw.vtx and b/models/engines/inline4l.sw.vtx differ
diff --git a/models/engines/inline4l.vvd b/models/engines/inline4l.vvd
index 01d96d381..7e40176f7 100644
Binary files a/models/engines/inline4l.vvd and b/models/engines/inline4l.vvd differ
diff --git a/models/engines/inline4m.dx80.vtx b/models/engines/inline4m.dx80.vtx
index 16084e948..250023cc7 100644
Binary files a/models/engines/inline4m.dx80.vtx and b/models/engines/inline4m.dx80.vtx differ
diff --git a/models/engines/inline4m.dx90.vtx b/models/engines/inline4m.dx90.vtx
index 372ec67d3..e487b3527 100644
Binary files a/models/engines/inline4m.dx90.vtx and b/models/engines/inline4m.dx90.vtx differ
diff --git a/models/engines/inline4m.mdl b/models/engines/inline4m.mdl
index b9f38a902..3f643b60e 100644
Binary files a/models/engines/inline4m.mdl and b/models/engines/inline4m.mdl differ
diff --git a/models/engines/inline4m.phy b/models/engines/inline4m.phy
index ee2d60a0a..d5db16dcf 100644
Binary files a/models/engines/inline4m.phy and b/models/engines/inline4m.phy differ
diff --git a/models/engines/inline4m.sw.vtx b/models/engines/inline4m.sw.vtx
index 0ed042802..04be85afd 100644
Binary files a/models/engines/inline4m.sw.vtx and b/models/engines/inline4m.sw.vtx differ
diff --git a/models/engines/inline4m.vvd b/models/engines/inline4m.vvd
index 6d81a26fc..4130c88a6 100644
Binary files a/models/engines/inline4m.vvd and b/models/engines/inline4m.vvd differ
diff --git a/models/engines/inline4s.dx80.vtx b/models/engines/inline4s.dx80.vtx
index a4fc417aa..8f6935ed4 100644
Binary files a/models/engines/inline4s.dx80.vtx and b/models/engines/inline4s.dx80.vtx differ
diff --git a/models/engines/inline4s.dx90.vtx b/models/engines/inline4s.dx90.vtx
index 28fd346b6..fe55d5c97 100644
Binary files a/models/engines/inline4s.dx90.vtx and b/models/engines/inline4s.dx90.vtx differ
diff --git a/models/engines/inline4s.mdl b/models/engines/inline4s.mdl
index d02492173..eaf0193d2 100644
Binary files a/models/engines/inline4s.mdl and b/models/engines/inline4s.mdl differ
diff --git a/models/engines/inline4s.phy b/models/engines/inline4s.phy
index b337f4196..1f8223630 100644
Binary files a/models/engines/inline4s.phy and b/models/engines/inline4s.phy differ
diff --git a/models/engines/inline4s.sw.vtx b/models/engines/inline4s.sw.vtx
index 779a68423..baeccabb7 100644
Binary files a/models/engines/inline4s.sw.vtx and b/models/engines/inline4s.sw.vtx differ
diff --git a/models/engines/inline4s.vvd b/models/engines/inline4s.vvd
index 3c35b7288..d7fa63ab6 100644
Binary files a/models/engines/inline4s.vvd and b/models/engines/inline4s.vvd differ
diff --git a/models/engines/inline5b.dx80.vtx b/models/engines/inline5b.dx80.vtx
new file mode 100644
index 000000000..aa841872b
Binary files /dev/null and b/models/engines/inline5b.dx80.vtx differ
diff --git a/models/engines/inline5b.dx90.vtx b/models/engines/inline5b.dx90.vtx
new file mode 100644
index 000000000..6d57674d7
Binary files /dev/null and b/models/engines/inline5b.dx90.vtx differ
diff --git a/models/engines/inline5b.mdl b/models/engines/inline5b.mdl
new file mode 100644
index 000000000..0bf580308
Binary files /dev/null and b/models/engines/inline5b.mdl differ
diff --git a/models/engines/inline5b.phy b/models/engines/inline5b.phy
new file mode 100644
index 000000000..30b552106
Binary files /dev/null and b/models/engines/inline5b.phy differ
diff --git a/models/engines/inline5b.sw.vtx b/models/engines/inline5b.sw.vtx
new file mode 100644
index 000000000..a7ef4c397
Binary files /dev/null and b/models/engines/inline5b.sw.vtx differ
diff --git a/models/engines/inline5b.vvd b/models/engines/inline5b.vvd
new file mode 100644
index 000000000..125074c81
Binary files /dev/null and b/models/engines/inline5b.vvd differ
diff --git a/models/engines/inline5m.dx80.vtx b/models/engines/inline5m.dx80.vtx
new file mode 100644
index 000000000..a1939175f
Binary files /dev/null and b/models/engines/inline5m.dx80.vtx differ
diff --git a/models/engines/inline5m.dx90.vtx b/models/engines/inline5m.dx90.vtx
new file mode 100644
index 000000000..687fc4d6a
Binary files /dev/null and b/models/engines/inline5m.dx90.vtx differ
diff --git a/models/engines/inline5m.mdl b/models/engines/inline5m.mdl
new file mode 100644
index 000000000..bd405c7da
Binary files /dev/null and b/models/engines/inline5m.mdl differ
diff --git a/models/engines/inline5m.phy b/models/engines/inline5m.phy
new file mode 100644
index 000000000..ed0817896
Binary files /dev/null and b/models/engines/inline5m.phy differ
diff --git a/models/engines/inline5m.sw.vtx b/models/engines/inline5m.sw.vtx
new file mode 100644
index 000000000..6eeb491fa
Binary files /dev/null and b/models/engines/inline5m.sw.vtx differ
diff --git a/models/engines/inline5m.vvd b/models/engines/inline5m.vvd
new file mode 100644
index 000000000..7e6d62dde
Binary files /dev/null and b/models/engines/inline5m.vvd differ
diff --git a/models/engines/inline5s.dx80.vtx b/models/engines/inline5s.dx80.vtx
new file mode 100644
index 000000000..fd3afa537
Binary files /dev/null and b/models/engines/inline5s.dx80.vtx differ
diff --git a/models/engines/inline5s.dx90.vtx b/models/engines/inline5s.dx90.vtx
new file mode 100644
index 000000000..3e5c954ad
Binary files /dev/null and b/models/engines/inline5s.dx90.vtx differ
diff --git a/models/engines/inline5s.mdl b/models/engines/inline5s.mdl
new file mode 100644
index 000000000..9626e7b13
Binary files /dev/null and b/models/engines/inline5s.mdl differ
diff --git a/models/engines/inline5s.phy b/models/engines/inline5s.phy
new file mode 100644
index 000000000..0778d3689
Binary files /dev/null and b/models/engines/inline5s.phy differ
diff --git a/models/engines/inline5s.sw.vtx b/models/engines/inline5s.sw.vtx
new file mode 100644
index 000000000..009e41468
Binary files /dev/null and b/models/engines/inline5s.sw.vtx differ
diff --git a/models/engines/inline5s.vvd b/models/engines/inline5s.vvd
new file mode 100644
index 000000000..404bad5b0
Binary files /dev/null and b/models/engines/inline5s.vvd differ
diff --git a/models/engines/inline6l.dx80.vtx b/models/engines/inline6l.dx80.vtx
index ffb7a873c..673e977e3 100644
Binary files a/models/engines/inline6l.dx80.vtx and b/models/engines/inline6l.dx80.vtx differ
diff --git a/models/engines/inline6l.dx90.vtx b/models/engines/inline6l.dx90.vtx
index 1401388d2..a819635b0 100644
Binary files a/models/engines/inline6l.dx90.vtx and b/models/engines/inline6l.dx90.vtx differ
diff --git a/models/engines/inline6l.mdl b/models/engines/inline6l.mdl
index 292244032..f793969d2 100644
Binary files a/models/engines/inline6l.mdl and b/models/engines/inline6l.mdl differ
diff --git a/models/engines/inline6l.phy b/models/engines/inline6l.phy
index 60a110f96..28652136d 100644
Binary files a/models/engines/inline6l.phy and b/models/engines/inline6l.phy differ
diff --git a/models/engines/inline6l.sw.vtx b/models/engines/inline6l.sw.vtx
index 59ff861c8..d543c42fb 100644
Binary files a/models/engines/inline6l.sw.vtx and b/models/engines/inline6l.sw.vtx differ
diff --git a/models/engines/inline6l.vvd b/models/engines/inline6l.vvd
index 95aa99a05..186fa6d4a 100644
Binary files a/models/engines/inline6l.vvd and b/models/engines/inline6l.vvd differ
diff --git a/models/engines/inline6m.dx80.vtx b/models/engines/inline6m.dx80.vtx
index 6c15a1dde..34dcad5ed 100644
Binary files a/models/engines/inline6m.dx80.vtx and b/models/engines/inline6m.dx80.vtx differ
diff --git a/models/engines/inline6m.dx90.vtx b/models/engines/inline6m.dx90.vtx
index 264269b1a..35e071080 100644
Binary files a/models/engines/inline6m.dx90.vtx and b/models/engines/inline6m.dx90.vtx differ
diff --git a/models/engines/inline6m.mdl b/models/engines/inline6m.mdl
index 9986d6283..ec6dcdf8c 100644
Binary files a/models/engines/inline6m.mdl and b/models/engines/inline6m.mdl differ
diff --git a/models/engines/inline6m.phy b/models/engines/inline6m.phy
index 7c4c1aaf1..e827e119b 100644
Binary files a/models/engines/inline6m.phy and b/models/engines/inline6m.phy differ
diff --git a/models/engines/inline6m.sw.vtx b/models/engines/inline6m.sw.vtx
index 9ec608f64..809bd4637 100644
Binary files a/models/engines/inline6m.sw.vtx and b/models/engines/inline6m.sw.vtx differ
diff --git a/models/engines/inline6m.vvd b/models/engines/inline6m.vvd
index cc13e0640..303ea3a40 100644
Binary files a/models/engines/inline6m.vvd and b/models/engines/inline6m.vvd differ
diff --git a/models/engines/inline6s.dx80.vtx b/models/engines/inline6s.dx80.vtx
index 2fe03ad06..7cae7b58b 100644
Binary files a/models/engines/inline6s.dx80.vtx and b/models/engines/inline6s.dx80.vtx differ
diff --git a/models/engines/inline6s.dx90.vtx b/models/engines/inline6s.dx90.vtx
index 8054ed701..15974ab43 100644
Binary files a/models/engines/inline6s.dx90.vtx and b/models/engines/inline6s.dx90.vtx differ
diff --git a/models/engines/inline6s.mdl b/models/engines/inline6s.mdl
index 3352251a5..0cc908d33 100644
Binary files a/models/engines/inline6s.mdl and b/models/engines/inline6s.mdl differ
diff --git a/models/engines/inline6s.phy b/models/engines/inline6s.phy
index bdaddcb9c..79c318291 100644
Binary files a/models/engines/inline6s.phy and b/models/engines/inline6s.phy differ
diff --git a/models/engines/inline6s.sw.vtx b/models/engines/inline6s.sw.vtx
index b64542461..dff4d29f1 100644
Binary files a/models/engines/inline6s.sw.vtx and b/models/engines/inline6s.sw.vtx differ
diff --git a/models/engines/inline6s.vvd b/models/engines/inline6s.vvd
index 53dcd22a5..7d9dc3da0 100644
Binary files a/models/engines/inline6s.vvd and b/models/engines/inline6s.vvd differ
diff --git a/models/engines/v-twinb.dx80.vtx b/models/engines/v-twinb.dx80.vtx
deleted file mode 100644
index 35b23648f..000000000
Binary files a/models/engines/v-twinb.dx80.vtx and /dev/null differ
diff --git a/models/engines/v-twinb.dx90.vtx b/models/engines/v-twinb.dx90.vtx
deleted file mode 100644
index f6ac6eddb..000000000
Binary files a/models/engines/v-twinb.dx90.vtx and /dev/null differ
diff --git a/models/engines/v-twinb.mdl b/models/engines/v-twinb.mdl
deleted file mode 100644
index 210ca5823..000000000
Binary files a/models/engines/v-twinb.mdl and /dev/null differ
diff --git a/models/engines/v-twinb.phy b/models/engines/v-twinb.phy
deleted file mode 100644
index 2efe73fc5..000000000
Binary files a/models/engines/v-twinb.phy and /dev/null differ
diff --git a/models/engines/v-twinb.sw.vtx b/models/engines/v-twinb.sw.vtx
deleted file mode 100644
index 696216116..000000000
Binary files a/models/engines/v-twinb.sw.vtx and /dev/null differ
diff --git a/models/engines/v-twinb.vvd b/models/engines/v-twinb.vvd
deleted file mode 100644
index 401eca417..000000000
Binary files a/models/engines/v-twinb.vvd and /dev/null differ
diff --git a/models/engines/v-twinl2.dx80.vtx b/models/engines/v-twinl2.dx80.vtx
new file mode 100644
index 000000000..c996c093c
Binary files /dev/null and b/models/engines/v-twinl2.dx80.vtx differ
diff --git a/models/engines/v-twinl2.dx90.vtx b/models/engines/v-twinl2.dx90.vtx
new file mode 100644
index 000000000..093ae28a9
Binary files /dev/null and b/models/engines/v-twinl2.dx90.vtx differ
diff --git a/models/engines/v-twinl2.mdl b/models/engines/v-twinl2.mdl
new file mode 100644
index 000000000..1e1a43e43
Binary files /dev/null and b/models/engines/v-twinl2.mdl differ
diff --git a/models/engines/v-twinl2.phy b/models/engines/v-twinl2.phy
new file mode 100644
index 000000000..4f30801f5
Binary files /dev/null and b/models/engines/v-twinl2.phy differ
diff --git a/models/engines/v-twinl2.sw.vtx b/models/engines/v-twinl2.sw.vtx
new file mode 100644
index 000000000..a8f86cd8e
Binary files /dev/null and b/models/engines/v-twinl2.sw.vtx differ
diff --git a/models/engines/v-twinl2.vvd b/models/engines/v-twinl2.vvd
new file mode 100644
index 000000000..d31196e44
Binary files /dev/null and b/models/engines/v-twinl2.vvd differ
diff --git a/models/engines/v-twinm.dx80.vtx b/models/engines/v-twinm.dx80.vtx
deleted file mode 100644
index b07a296a3..000000000
Binary files a/models/engines/v-twinm.dx80.vtx and /dev/null differ
diff --git a/models/engines/v-twinm.dx90.vtx b/models/engines/v-twinm.dx90.vtx
deleted file mode 100644
index 787135a3f..000000000
Binary files a/models/engines/v-twinm.dx90.vtx and /dev/null differ
diff --git a/models/engines/v-twinm.mdl b/models/engines/v-twinm.mdl
deleted file mode 100644
index 87c2912a3..000000000
Binary files a/models/engines/v-twinm.mdl and /dev/null differ
diff --git a/models/engines/v-twinm.phy b/models/engines/v-twinm.phy
deleted file mode 100644
index 415bc87be..000000000
Binary files a/models/engines/v-twinm.phy and /dev/null differ
diff --git a/models/engines/v-twinm.sw.vtx b/models/engines/v-twinm.sw.vtx
deleted file mode 100644
index 4ecc1ae0c..000000000
Binary files a/models/engines/v-twinm.sw.vtx and /dev/null differ
diff --git a/models/engines/v-twinm.vvd b/models/engines/v-twinm.vvd
deleted file mode 100644
index 26e9a8d38..000000000
Binary files a/models/engines/v-twinm.vvd and /dev/null differ
diff --git a/models/engines/v-twinm2.dx80.vtx b/models/engines/v-twinm2.dx80.vtx
new file mode 100644
index 000000000..1ead21b58
Binary files /dev/null and b/models/engines/v-twinm2.dx80.vtx differ
diff --git a/models/engines/v-twinm2.dx90.vtx b/models/engines/v-twinm2.dx90.vtx
new file mode 100644
index 000000000..fcc6358c2
Binary files /dev/null and b/models/engines/v-twinm2.dx90.vtx differ
diff --git a/models/engines/v-twinm2.mdl b/models/engines/v-twinm2.mdl
new file mode 100644
index 000000000..918809755
Binary files /dev/null and b/models/engines/v-twinm2.mdl differ
diff --git a/models/engines/v-twinm2.phy b/models/engines/v-twinm2.phy
new file mode 100644
index 000000000..873c7555a
Binary files /dev/null and b/models/engines/v-twinm2.phy differ
diff --git a/models/engines/v-twinm2.sw.vtx b/models/engines/v-twinm2.sw.vtx
new file mode 100644
index 000000000..aa7927f4a
Binary files /dev/null and b/models/engines/v-twinm2.sw.vtx differ
diff --git a/models/engines/v-twinm2.vvd b/models/engines/v-twinm2.vvd
new file mode 100644
index 000000000..22a935e90
Binary files /dev/null and b/models/engines/v-twinm2.vvd differ
diff --git a/models/engines/v-twins.dx80.vtx b/models/engines/v-twins.dx80.vtx
deleted file mode 100644
index 28005ad6e..000000000
Binary files a/models/engines/v-twins.dx80.vtx and /dev/null differ
diff --git a/models/engines/v-twins.dx90.vtx b/models/engines/v-twins.dx90.vtx
deleted file mode 100644
index bbd58e455..000000000
Binary files a/models/engines/v-twins.dx90.vtx and /dev/null differ
diff --git a/models/engines/v-twins.mdl b/models/engines/v-twins.mdl
deleted file mode 100644
index 73279024c..000000000
Binary files a/models/engines/v-twins.mdl and /dev/null differ
diff --git a/models/engines/v-twins.phy b/models/engines/v-twins.phy
deleted file mode 100644
index 296674ddc..000000000
Binary files a/models/engines/v-twins.phy and /dev/null differ
diff --git a/models/engines/v-twins.sw.vtx b/models/engines/v-twins.sw.vtx
deleted file mode 100644
index 3af8678f9..000000000
Binary files a/models/engines/v-twins.sw.vtx and /dev/null differ
diff --git a/models/engines/v-twins.vvd b/models/engines/v-twins.vvd
deleted file mode 100644
index 1b7b8af8d..000000000
Binary files a/models/engines/v-twins.vvd and /dev/null differ
diff --git a/models/engines/v-twins2.dx80.vtx b/models/engines/v-twins2.dx80.vtx
new file mode 100644
index 000000000..edd3a6e76
Binary files /dev/null and b/models/engines/v-twins2.dx80.vtx differ
diff --git a/models/engines/v-twins2.dx90.vtx b/models/engines/v-twins2.dx90.vtx
new file mode 100644
index 000000000..4620159a2
Binary files /dev/null and b/models/engines/v-twins2.dx90.vtx differ
diff --git a/models/engines/v-twins2.mdl b/models/engines/v-twins2.mdl
new file mode 100644
index 000000000..c42e3e560
Binary files /dev/null and b/models/engines/v-twins2.mdl differ
diff --git a/models/engines/v-twins2.phy b/models/engines/v-twins2.phy
new file mode 100644
index 000000000..de9614681
Binary files /dev/null and b/models/engines/v-twins2.phy differ
diff --git a/models/engines/v-twins2.sw.vtx b/models/engines/v-twins2.sw.vtx
new file mode 100644
index 000000000..5af81a9b8
Binary files /dev/null and b/models/engines/v-twins2.sw.vtx differ
diff --git a/models/engines/v-twins2.vvd b/models/engines/v-twins2.vvd
new file mode 100644
index 000000000..7f36c97b3
Binary files /dev/null and b/models/engines/v-twins2.vvd differ
diff --git a/models/engines/v10big.dx80.vtx b/models/engines/v10big.dx80.vtx
new file mode 100644
index 000000000..1cefeda18
Binary files /dev/null and b/models/engines/v10big.dx80.vtx differ
diff --git a/models/engines/v10big.dx90.vtx b/models/engines/v10big.dx90.vtx
new file mode 100644
index 000000000..992c2940f
Binary files /dev/null and b/models/engines/v10big.dx90.vtx differ
diff --git a/models/engines/v10big.mdl b/models/engines/v10big.mdl
new file mode 100644
index 000000000..a162dc866
Binary files /dev/null and b/models/engines/v10big.mdl differ
diff --git a/models/engines/v10big.phy b/models/engines/v10big.phy
new file mode 100644
index 000000000..fb4e5ff51
Binary files /dev/null and b/models/engines/v10big.phy differ
diff --git a/models/engines/v10big.sw.vtx b/models/engines/v10big.sw.vtx
new file mode 100644
index 000000000..9da820893
Binary files /dev/null and b/models/engines/v10big.sw.vtx differ
diff --git a/models/engines/v10big.vvd b/models/engines/v10big.vvd
new file mode 100644
index 000000000..8d65a1657
Binary files /dev/null and b/models/engines/v10big.vvd differ
diff --git a/models/engines/v10med.dx80.vtx b/models/engines/v10med.dx80.vtx
new file mode 100644
index 000000000..e75e799f4
Binary files /dev/null and b/models/engines/v10med.dx80.vtx differ
diff --git a/models/engines/v10med.dx90.vtx b/models/engines/v10med.dx90.vtx
new file mode 100644
index 000000000..dbf0d547c
Binary files /dev/null and b/models/engines/v10med.dx90.vtx differ
diff --git a/models/engines/v10med.mdl b/models/engines/v10med.mdl
new file mode 100644
index 000000000..745b4de3f
Binary files /dev/null and b/models/engines/v10med.mdl differ
diff --git a/models/engines/v10med.phy b/models/engines/v10med.phy
new file mode 100644
index 000000000..4f28282cf
Binary files /dev/null and b/models/engines/v10med.phy differ
diff --git a/models/engines/v10med.sw.vtx b/models/engines/v10med.sw.vtx
new file mode 100644
index 000000000..7c23d5bba
Binary files /dev/null and b/models/engines/v10med.sw.vtx differ
diff --git a/models/engines/v10med.vvd b/models/engines/v10med.vvd
new file mode 100644
index 000000000..bc9837af1
Binary files /dev/null and b/models/engines/v10med.vvd differ
diff --git a/models/engines/v10sml.dx80.vtx b/models/engines/v10sml.dx80.vtx
new file mode 100644
index 000000000..c99e79b02
Binary files /dev/null and b/models/engines/v10sml.dx80.vtx differ
diff --git a/models/engines/v10sml.dx90.vtx b/models/engines/v10sml.dx90.vtx
new file mode 100644
index 000000000..7e403eab6
Binary files /dev/null and b/models/engines/v10sml.dx90.vtx differ
diff --git a/models/engines/v10sml.mdl b/models/engines/v10sml.mdl
new file mode 100644
index 000000000..d797c523c
Binary files /dev/null and b/models/engines/v10sml.mdl differ
diff --git a/models/engines/v10sml.phy b/models/engines/v10sml.phy
new file mode 100644
index 000000000..e86782ea1
Binary files /dev/null and b/models/engines/v10sml.phy differ
diff --git a/models/engines/v10sml.sw.vtx b/models/engines/v10sml.sw.vtx
new file mode 100644
index 000000000..547a5b733
Binary files /dev/null and b/models/engines/v10sml.sw.vtx differ
diff --git a/models/engines/v10sml.vvd b/models/engines/v10sml.vvd
new file mode 100644
index 000000000..cfbd66bc7
Binary files /dev/null and b/models/engines/v10sml.vvd differ
diff --git a/models/engines/v12l.dx80.vtx b/models/engines/v12l.dx80.vtx
index 1db6b9fe9..f837dcc41 100644
Binary files a/models/engines/v12l.dx80.vtx and b/models/engines/v12l.dx80.vtx differ
diff --git a/models/engines/v12l.dx90.vtx b/models/engines/v12l.dx90.vtx
index a4428b875..81e13a94f 100644
Binary files a/models/engines/v12l.dx90.vtx and b/models/engines/v12l.dx90.vtx differ
diff --git a/models/engines/v12l.mdl b/models/engines/v12l.mdl
index f245fbb9c..88bdd55eb 100644
Binary files a/models/engines/v12l.mdl and b/models/engines/v12l.mdl differ
diff --git a/models/engines/v12l.phy b/models/engines/v12l.phy
index aea9bf7ae..6ea852025 100644
Binary files a/models/engines/v12l.phy and b/models/engines/v12l.phy differ
diff --git a/models/engines/v12l.sw.vtx b/models/engines/v12l.sw.vtx
index 7b34b86d0..50632ec12 100644
Binary files a/models/engines/v12l.sw.vtx and b/models/engines/v12l.sw.vtx differ
diff --git a/models/engines/v12l.vvd b/models/engines/v12l.vvd
index ab955a98f..f33fb389b 100644
Binary files a/models/engines/v12l.vvd and b/models/engines/v12l.vvd differ
diff --git a/models/engines/v12m.dx80.vtx b/models/engines/v12m.dx80.vtx
index 8eb75b769..3db7484dd 100644
Binary files a/models/engines/v12m.dx80.vtx and b/models/engines/v12m.dx80.vtx differ
diff --git a/models/engines/v12m.dx90.vtx b/models/engines/v12m.dx90.vtx
index 25f4e6b95..427b241c3 100644
Binary files a/models/engines/v12m.dx90.vtx and b/models/engines/v12m.dx90.vtx differ
diff --git a/models/engines/v12m.mdl b/models/engines/v12m.mdl
index a4bb52a75..396ea1447 100644
Binary files a/models/engines/v12m.mdl and b/models/engines/v12m.mdl differ
diff --git a/models/engines/v12m.phy b/models/engines/v12m.phy
index b619806f2..1cc889e49 100644
Binary files a/models/engines/v12m.phy and b/models/engines/v12m.phy differ
diff --git a/models/engines/v12m.sw.vtx b/models/engines/v12m.sw.vtx
index 38e14b81e..608cc29ef 100644
Binary files a/models/engines/v12m.sw.vtx and b/models/engines/v12m.sw.vtx differ
diff --git a/models/engines/v12m.vvd b/models/engines/v12m.vvd
index 45c1cd491..cd181dda1 100644
Binary files a/models/engines/v12m.vvd and b/models/engines/v12m.vvd differ
diff --git a/models/engines/v12s.dx80.vtx b/models/engines/v12s.dx80.vtx
index fa860f552..79a4ac983 100644
Binary files a/models/engines/v12s.dx80.vtx and b/models/engines/v12s.dx80.vtx differ
diff --git a/models/engines/v12s.dx90.vtx b/models/engines/v12s.dx90.vtx
index 21382224f..f3e4cfbd1 100644
Binary files a/models/engines/v12s.dx90.vtx and b/models/engines/v12s.dx90.vtx differ
diff --git a/models/engines/v12s.mdl b/models/engines/v12s.mdl
index 0b261dcee..373baa4e8 100644
Binary files a/models/engines/v12s.mdl and b/models/engines/v12s.mdl differ
diff --git a/models/engines/v12s.phy b/models/engines/v12s.phy
index 88daee303..36ba95125 100644
Binary files a/models/engines/v12s.phy and b/models/engines/v12s.phy differ
diff --git a/models/engines/v12s.sw.vtx b/models/engines/v12s.sw.vtx
index d0f2df53c..199d892d3 100644
Binary files a/models/engines/v12s.sw.vtx and b/models/engines/v12s.sw.vtx differ
diff --git a/models/engines/v12s.vvd b/models/engines/v12s.vvd
index 607fe388f..0aa481c37 100644
Binary files a/models/engines/v12s.vvd and b/models/engines/v12s.vvd differ
diff --git a/models/engines/v4l.dx80.vtx b/models/engines/v4l.dx80.vtx
new file mode 100644
index 000000000..3d2a008f4
Binary files /dev/null and b/models/engines/v4l.dx80.vtx differ
diff --git a/models/engines/v4l.dx90.vtx b/models/engines/v4l.dx90.vtx
new file mode 100644
index 000000000..15d46de78
Binary files /dev/null and b/models/engines/v4l.dx90.vtx differ
diff --git a/models/engines/v4l.mdl b/models/engines/v4l.mdl
new file mode 100644
index 000000000..a9acfa0b8
Binary files /dev/null and b/models/engines/v4l.mdl differ
diff --git a/models/engines/v4l.phy b/models/engines/v4l.phy
new file mode 100644
index 000000000..597bb5d1f
Binary files /dev/null and b/models/engines/v4l.phy differ
diff --git a/models/engines/v4l.sw.vtx b/models/engines/v4l.sw.vtx
new file mode 100644
index 000000000..48abf70e8
Binary files /dev/null and b/models/engines/v4l.sw.vtx differ
diff --git a/models/engines/v4l.vvd b/models/engines/v4l.vvd
new file mode 100644
index 000000000..274adbb48
Binary files /dev/null and b/models/engines/v4l.vvd differ
diff --git a/models/engines/v4m.dx80.vtx b/models/engines/v4m.dx80.vtx
new file mode 100644
index 000000000..db5fb74db
Binary files /dev/null and b/models/engines/v4m.dx80.vtx differ
diff --git a/models/engines/v4m.dx90.vtx b/models/engines/v4m.dx90.vtx
new file mode 100644
index 000000000..934434f1a
Binary files /dev/null and b/models/engines/v4m.dx90.vtx differ
diff --git a/models/engines/v4m.mdl b/models/engines/v4m.mdl
new file mode 100644
index 000000000..93f750421
Binary files /dev/null and b/models/engines/v4m.mdl differ
diff --git a/models/engines/v4m.phy b/models/engines/v4m.phy
new file mode 100644
index 000000000..b4d2be5fc
Binary files /dev/null and b/models/engines/v4m.phy differ
diff --git a/models/engines/v4m.sw.vtx b/models/engines/v4m.sw.vtx
new file mode 100644
index 000000000..a9a3aa97a
Binary files /dev/null and b/models/engines/v4m.sw.vtx differ
diff --git a/models/engines/v4m.vvd b/models/engines/v4m.vvd
new file mode 100644
index 000000000..06b967bc6
Binary files /dev/null and b/models/engines/v4m.vvd differ
diff --git a/models/engines/v4s.dx80.vtx b/models/engines/v4s.dx80.vtx
new file mode 100644
index 000000000..1084cb05f
Binary files /dev/null and b/models/engines/v4s.dx80.vtx differ
diff --git a/models/engines/v4s.dx90.vtx b/models/engines/v4s.dx90.vtx
new file mode 100644
index 000000000..f56514b42
Binary files /dev/null and b/models/engines/v4s.dx90.vtx differ
diff --git a/models/engines/v4s.mdl b/models/engines/v4s.mdl
new file mode 100644
index 000000000..75d78fdb7
Binary files /dev/null and b/models/engines/v4s.mdl differ
diff --git a/models/engines/v4s.phy b/models/engines/v4s.phy
new file mode 100644
index 000000000..4ac14cb06
Binary files /dev/null and b/models/engines/v4s.phy differ
diff --git a/models/engines/v4s.sw.vtx b/models/engines/v4s.sw.vtx
new file mode 100644
index 000000000..574f00737
Binary files /dev/null and b/models/engines/v4s.sw.vtx differ
diff --git a/models/engines/v4s.vvd b/models/engines/v4s.vvd
new file mode 100644
index 000000000..0d3dfbb54
Binary files /dev/null and b/models/engines/v4s.vvd differ
diff --git a/models/engines/v6large.dx80.vtx b/models/engines/v6large.dx80.vtx
index cf57d446d..f838d01a7 100644
Binary files a/models/engines/v6large.dx80.vtx and b/models/engines/v6large.dx80.vtx differ
diff --git a/models/engines/v6large.dx90.vtx b/models/engines/v6large.dx90.vtx
index de0f3101b..f9fb0fb6f 100644
Binary files a/models/engines/v6large.dx90.vtx and b/models/engines/v6large.dx90.vtx differ
diff --git a/models/engines/v6large.mdl b/models/engines/v6large.mdl
index 39532cc71..510de6010 100644
Binary files a/models/engines/v6large.mdl and b/models/engines/v6large.mdl differ
diff --git a/models/engines/v6large.phy b/models/engines/v6large.phy
index 0b46a21a6..ce1f6b453 100644
Binary files a/models/engines/v6large.phy and b/models/engines/v6large.phy differ
diff --git a/models/engines/v6large.sw.vtx b/models/engines/v6large.sw.vtx
index 4b9a07e66..edb14a80c 100644
Binary files a/models/engines/v6large.sw.vtx and b/models/engines/v6large.sw.vtx differ
diff --git a/models/engines/v6large.vvd b/models/engines/v6large.vvd
index 15dc28174..b76e9b2ee 100644
Binary files a/models/engines/v6large.vvd and b/models/engines/v6large.vvd differ
diff --git a/models/engines/v6med.dx80.vtx b/models/engines/v6med.dx80.vtx
index aeb99f36d..7baf8096b 100644
Binary files a/models/engines/v6med.dx80.vtx and b/models/engines/v6med.dx80.vtx differ
diff --git a/models/engines/v6med.dx90.vtx b/models/engines/v6med.dx90.vtx
index 1bfe1b0ce..0b361615a 100644
Binary files a/models/engines/v6med.dx90.vtx and b/models/engines/v6med.dx90.vtx differ
diff --git a/models/engines/v6med.mdl b/models/engines/v6med.mdl
index 840b87255..33c2effad 100644
Binary files a/models/engines/v6med.mdl and b/models/engines/v6med.mdl differ
diff --git a/models/engines/v6med.phy b/models/engines/v6med.phy
index cadd0cd4f..be1264538 100644
Binary files a/models/engines/v6med.phy and b/models/engines/v6med.phy differ
diff --git a/models/engines/v6med.sw.vtx b/models/engines/v6med.sw.vtx
index 58a1e5236..dc82e4daf 100644
Binary files a/models/engines/v6med.sw.vtx and b/models/engines/v6med.sw.vtx differ
diff --git a/models/engines/v6med.vvd b/models/engines/v6med.vvd
index 6e4d30e82..98b7d9512 100644
Binary files a/models/engines/v6med.vvd and b/models/engines/v6med.vvd differ
diff --git a/models/engines/v6small.dx80.vtx b/models/engines/v6small.dx80.vtx
index 0ceb695d3..e2364b076 100644
Binary files a/models/engines/v6small.dx80.vtx and b/models/engines/v6small.dx80.vtx differ
diff --git a/models/engines/v6small.dx90.vtx b/models/engines/v6small.dx90.vtx
index fd3729968..ca912d96d 100644
Binary files a/models/engines/v6small.dx90.vtx and b/models/engines/v6small.dx90.vtx differ
diff --git a/models/engines/v6small.mdl b/models/engines/v6small.mdl
index 68055f149..2283c0331 100644
Binary files a/models/engines/v6small.mdl and b/models/engines/v6small.mdl differ
diff --git a/models/engines/v6small.phy b/models/engines/v6small.phy
index 880b51725..46fac2eb0 100644
Binary files a/models/engines/v6small.phy and b/models/engines/v6small.phy differ
diff --git a/models/engines/v6small.sw.vtx b/models/engines/v6small.sw.vtx
index f9d459618..edc4709ee 100644
Binary files a/models/engines/v6small.sw.vtx and b/models/engines/v6small.sw.vtx differ
diff --git a/models/engines/v6small.vvd b/models/engines/v6small.vvd
index 7016a6656..bd2a8b546 100644
Binary files a/models/engines/v6small.vvd and b/models/engines/v6small.vvd differ
diff --git a/models/engines/v8l.dx80.vtx b/models/engines/v8l.dx80.vtx
index 9d4c10de8..87435f83b 100644
Binary files a/models/engines/v8l.dx80.vtx and b/models/engines/v8l.dx80.vtx differ
diff --git a/models/engines/v8l.dx90.vtx b/models/engines/v8l.dx90.vtx
index 2dcc4fada..b9b6a784f 100644
Binary files a/models/engines/v8l.dx90.vtx and b/models/engines/v8l.dx90.vtx differ
diff --git a/models/engines/v8l.mdl b/models/engines/v8l.mdl
index 83491353c..5d67bfe39 100644
Binary files a/models/engines/v8l.mdl and b/models/engines/v8l.mdl differ
diff --git a/models/engines/v8l.phy b/models/engines/v8l.phy
index ca3c90616..809307716 100644
Binary files a/models/engines/v8l.phy and b/models/engines/v8l.phy differ
diff --git a/models/engines/v8l.sw.vtx b/models/engines/v8l.sw.vtx
index c4c8ed181..40cfec75d 100644
Binary files a/models/engines/v8l.sw.vtx and b/models/engines/v8l.sw.vtx differ
diff --git a/models/engines/v8l.vvd b/models/engines/v8l.vvd
index b14e5b82d..1dfaf4a17 100644
Binary files a/models/engines/v8l.vvd and b/models/engines/v8l.vvd differ
diff --git a/models/engines/v8m.dx80.vtx b/models/engines/v8m.dx80.vtx
index 59654166a..3c58a68b9 100644
Binary files a/models/engines/v8m.dx80.vtx and b/models/engines/v8m.dx80.vtx differ
diff --git a/models/engines/v8m.dx90.vtx b/models/engines/v8m.dx90.vtx
index 5cb80d49d..e51125890 100644
Binary files a/models/engines/v8m.dx90.vtx and b/models/engines/v8m.dx90.vtx differ
diff --git a/models/engines/v8m.mdl b/models/engines/v8m.mdl
index 75b0effd1..e51f6d7cd 100644
Binary files a/models/engines/v8m.mdl and b/models/engines/v8m.mdl differ
diff --git a/models/engines/v8m.phy b/models/engines/v8m.phy
index 3ee195272..ee896be23 100644
Binary files a/models/engines/v8m.phy and b/models/engines/v8m.phy differ
diff --git a/models/engines/v8m.sw.vtx b/models/engines/v8m.sw.vtx
index 60023673b..109e2109c 100644
Binary files a/models/engines/v8m.sw.vtx and b/models/engines/v8m.sw.vtx differ
diff --git a/models/engines/v8m.vvd b/models/engines/v8m.vvd
index da144878b..e2470731a 100644
Binary files a/models/engines/v8m.vvd and b/models/engines/v8m.vvd differ
diff --git a/models/engines/v8s.dx80.vtx b/models/engines/v8s.dx80.vtx
index dfb98f60e..94330fb41 100644
Binary files a/models/engines/v8s.dx80.vtx and b/models/engines/v8s.dx80.vtx differ
diff --git a/models/engines/v8s.dx90.vtx b/models/engines/v8s.dx90.vtx
index ace60b6af..8523d4f77 100644
Binary files a/models/engines/v8s.dx90.vtx and b/models/engines/v8s.dx90.vtx differ
diff --git a/models/engines/v8s.mdl b/models/engines/v8s.mdl
index 2eb3c421d..ad1589f99 100644
Binary files a/models/engines/v8s.mdl and b/models/engines/v8s.mdl differ
diff --git a/models/engines/v8s.phy b/models/engines/v8s.phy
index 52f2e7453..5482b6673 100644
Binary files a/models/engines/v8s.phy and b/models/engines/v8s.phy differ
diff --git a/models/engines/v8s.sw.vtx b/models/engines/v8s.sw.vtx
index 240578911..f930cb8d0 100644
Binary files a/models/engines/v8s.sw.vtx and b/models/engines/v8s.sw.vtx differ
diff --git a/models/engines/v8s.vvd b/models/engines/v8s.vvd
index 51c253c7f..22f6f4b97 100644
Binary files a/models/engines/v8s.vvd and b/models/engines/v8s.vvd differ
diff --git a/models/engines/wankel_2_med.dx80.vtx b/models/engines/wankel_2_med.dx80.vtx
new file mode 100644
index 000000000..697c82690
Binary files /dev/null and b/models/engines/wankel_2_med.dx80.vtx differ
diff --git a/models/engines/wankel_2_med.dx90.vtx b/models/engines/wankel_2_med.dx90.vtx
new file mode 100644
index 000000000..e94c50556
Binary files /dev/null and b/models/engines/wankel_2_med.dx90.vtx differ
diff --git a/models/engines/wankel_2_med.mdl b/models/engines/wankel_2_med.mdl
new file mode 100644
index 000000000..f376ec20f
Binary files /dev/null and b/models/engines/wankel_2_med.mdl differ
diff --git a/models/engines/wankel_2_med.phy b/models/engines/wankel_2_med.phy
new file mode 100644
index 000000000..14945d783
Binary files /dev/null and b/models/engines/wankel_2_med.phy differ
diff --git a/models/engines/wankel_2_med.sw.vtx b/models/engines/wankel_2_med.sw.vtx
new file mode 100644
index 000000000..4e7ee4809
Binary files /dev/null and b/models/engines/wankel_2_med.sw.vtx differ
diff --git a/models/engines/wankel_2_med.vvd b/models/engines/wankel_2_med.vvd
new file mode 100644
index 000000000..f8644c24d
Binary files /dev/null and b/models/engines/wankel_2_med.vvd differ
diff --git a/models/engines/wankel_2_small.dx80.vtx b/models/engines/wankel_2_small.dx80.vtx
new file mode 100644
index 000000000..0a588a2de
Binary files /dev/null and b/models/engines/wankel_2_small.dx80.vtx differ
diff --git a/models/engines/wankel_2_small.dx90.vtx b/models/engines/wankel_2_small.dx90.vtx
new file mode 100644
index 000000000..d71a2c993
Binary files /dev/null and b/models/engines/wankel_2_small.dx90.vtx differ
diff --git a/models/engines/wankel_2_small.mdl b/models/engines/wankel_2_small.mdl
new file mode 100644
index 000000000..5e4793c37
Binary files /dev/null and b/models/engines/wankel_2_small.mdl differ
diff --git a/models/engines/wankel_2_small.phy b/models/engines/wankel_2_small.phy
new file mode 100644
index 000000000..5d30c1ce2
Binary files /dev/null and b/models/engines/wankel_2_small.phy differ
diff --git a/models/engines/wankel_2_small.sw.vtx b/models/engines/wankel_2_small.sw.vtx
new file mode 100644
index 000000000..ee3af455e
Binary files /dev/null and b/models/engines/wankel_2_small.sw.vtx differ
diff --git a/models/engines/wankel_2_small.vvd b/models/engines/wankel_2_small.vvd
new file mode 100644
index 000000000..e5df8e7ee
Binary files /dev/null and b/models/engines/wankel_2_small.vvd differ
diff --git a/models/engines/wankel_3_med.dx80.vtx b/models/engines/wankel_3_med.dx80.vtx
new file mode 100644
index 000000000..9f8096fbe
Binary files /dev/null and b/models/engines/wankel_3_med.dx80.vtx differ
diff --git a/models/engines/wankel_3_med.dx90.vtx b/models/engines/wankel_3_med.dx90.vtx
new file mode 100644
index 000000000..d111f144f
Binary files /dev/null and b/models/engines/wankel_3_med.dx90.vtx differ
diff --git a/models/engines/wankel_3_med.mdl b/models/engines/wankel_3_med.mdl
new file mode 100644
index 000000000..adfcab779
Binary files /dev/null and b/models/engines/wankel_3_med.mdl differ
diff --git a/models/engines/wankel_3_med.phy b/models/engines/wankel_3_med.phy
new file mode 100644
index 000000000..839aca090
Binary files /dev/null and b/models/engines/wankel_3_med.phy differ
diff --git a/models/engines/wankel_3_med.sw.vtx b/models/engines/wankel_3_med.sw.vtx
new file mode 100644
index 000000000..ba321968c
Binary files /dev/null and b/models/engines/wankel_3_med.sw.vtx differ
diff --git a/models/engines/wankel_3_med.vvd b/models/engines/wankel_3_med.vvd
new file mode 100644
index 000000000..0ed0f6e31
Binary files /dev/null and b/models/engines/wankel_3_med.vvd differ
diff --git a/models/engines/wankel_4_med.dx80.vtx b/models/engines/wankel_4_med.dx80.vtx
new file mode 100644
index 000000000..c2334f74e
Binary files /dev/null and b/models/engines/wankel_4_med.dx80.vtx differ
diff --git a/models/engines/wankel_4_med.dx90.vtx b/models/engines/wankel_4_med.dx90.vtx
new file mode 100644
index 000000000..3c007823e
Binary files /dev/null and b/models/engines/wankel_4_med.dx90.vtx differ
diff --git a/models/engines/wankel_4_med.mdl b/models/engines/wankel_4_med.mdl
new file mode 100644
index 000000000..1e958a43e
Binary files /dev/null and b/models/engines/wankel_4_med.mdl differ
diff --git a/models/engines/wankel_4_med.phy b/models/engines/wankel_4_med.phy
new file mode 100644
index 000000000..fa1b83487
Binary files /dev/null and b/models/engines/wankel_4_med.phy differ
diff --git a/models/engines/wankel_4_med.sw.vtx b/models/engines/wankel_4_med.sw.vtx
new file mode 100644
index 000000000..09e10f27d
Binary files /dev/null and b/models/engines/wankel_4_med.sw.vtx differ
diff --git a/models/engines/wankel_4_med.vvd b/models/engines/wankel_4_med.vvd
new file mode 100644
index 000000000..913ad5768
Binary files /dev/null and b/models/engines/wankel_4_med.vvd differ
diff --git a/models/fueltank/fueltank_1x1x1.dx80.vtx b/models/fueltank/fueltank_1x1x1.dx80.vtx
new file mode 100644
index 000000000..e493a698c
Binary files /dev/null and b/models/fueltank/fueltank_1x1x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x1x1.dx90.vtx b/models/fueltank/fueltank_1x1x1.dx90.vtx
new file mode 100644
index 000000000..6edebab64
Binary files /dev/null and b/models/fueltank/fueltank_1x1x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x1x1.mdl b/models/fueltank/fueltank_1x1x1.mdl
new file mode 100644
index 000000000..1ad23933f
Binary files /dev/null and b/models/fueltank/fueltank_1x1x1.mdl differ
diff --git a/models/fueltank/fueltank_1x1x1.phy b/models/fueltank/fueltank_1x1x1.phy
new file mode 100644
index 000000000..1ee28d817
Binary files /dev/null and b/models/fueltank/fueltank_1x1x1.phy differ
diff --git a/models/fueltank/fueltank_1x1x1.sw.vtx b/models/fueltank/fueltank_1x1x1.sw.vtx
new file mode 100644
index 000000000..13ff71509
Binary files /dev/null and b/models/fueltank/fueltank_1x1x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x1x1.vvd b/models/fueltank/fueltank_1x1x1.vvd
new file mode 100644
index 000000000..dbd9fb25d
Binary files /dev/null and b/models/fueltank/fueltank_1x1x1.vvd differ
diff --git a/models/fueltank/fueltank_1x1x2.dx80.vtx b/models/fueltank/fueltank_1x1x2.dx80.vtx
new file mode 100644
index 000000000..2944049ba
Binary files /dev/null and b/models/fueltank/fueltank_1x1x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x1x2.dx90.vtx b/models/fueltank/fueltank_1x1x2.dx90.vtx
new file mode 100644
index 000000000..a07871161
Binary files /dev/null and b/models/fueltank/fueltank_1x1x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x1x2.mdl b/models/fueltank/fueltank_1x1x2.mdl
new file mode 100644
index 000000000..6b36e219c
Binary files /dev/null and b/models/fueltank/fueltank_1x1x2.mdl differ
diff --git a/models/fueltank/fueltank_1x1x2.phy b/models/fueltank/fueltank_1x1x2.phy
new file mode 100644
index 000000000..adde009b6
Binary files /dev/null and b/models/fueltank/fueltank_1x1x2.phy differ
diff --git a/models/fueltank/fueltank_1x1x2.sw.vtx b/models/fueltank/fueltank_1x1x2.sw.vtx
new file mode 100644
index 000000000..55e7bee34
Binary files /dev/null and b/models/fueltank/fueltank_1x1x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x1x2.vvd b/models/fueltank/fueltank_1x1x2.vvd
new file mode 100644
index 000000000..807a733cb
Binary files /dev/null and b/models/fueltank/fueltank_1x1x2.vvd differ
diff --git a/models/fueltank/fueltank_1x1x4.dx80.vtx b/models/fueltank/fueltank_1x1x4.dx80.vtx
new file mode 100644
index 000000000..c369ee827
Binary files /dev/null and b/models/fueltank/fueltank_1x1x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x1x4.dx90.vtx b/models/fueltank/fueltank_1x1x4.dx90.vtx
new file mode 100644
index 000000000..f24f4265a
Binary files /dev/null and b/models/fueltank/fueltank_1x1x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x1x4.mdl b/models/fueltank/fueltank_1x1x4.mdl
new file mode 100644
index 000000000..e7940d078
Binary files /dev/null and b/models/fueltank/fueltank_1x1x4.mdl differ
diff --git a/models/fueltank/fueltank_1x1x4.phy b/models/fueltank/fueltank_1x1x4.phy
new file mode 100644
index 000000000..bd08807fb
Binary files /dev/null and b/models/fueltank/fueltank_1x1x4.phy differ
diff --git a/models/fueltank/fueltank_1x1x4.sw.vtx b/models/fueltank/fueltank_1x1x4.sw.vtx
new file mode 100644
index 000000000..1e2213eb5
Binary files /dev/null and b/models/fueltank/fueltank_1x1x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x1x4.vvd b/models/fueltank/fueltank_1x1x4.vvd
new file mode 100644
index 000000000..7f096c65d
Binary files /dev/null and b/models/fueltank/fueltank_1x1x4.vvd differ
diff --git a/models/fueltank/fueltank_1x2x1.dx80.vtx b/models/fueltank/fueltank_1x2x1.dx80.vtx
new file mode 100644
index 000000000..6689e4bc6
Binary files /dev/null and b/models/fueltank/fueltank_1x2x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x2x1.dx90.vtx b/models/fueltank/fueltank_1x2x1.dx90.vtx
new file mode 100644
index 000000000..3c722328e
Binary files /dev/null and b/models/fueltank/fueltank_1x2x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x2x1.mdl b/models/fueltank/fueltank_1x2x1.mdl
new file mode 100644
index 000000000..c79cd12a4
Binary files /dev/null and b/models/fueltank/fueltank_1x2x1.mdl differ
diff --git a/models/fueltank/fueltank_1x2x1.phy b/models/fueltank/fueltank_1x2x1.phy
new file mode 100644
index 000000000..35310c43c
Binary files /dev/null and b/models/fueltank/fueltank_1x2x1.phy differ
diff --git a/models/fueltank/fueltank_1x2x1.sw.vtx b/models/fueltank/fueltank_1x2x1.sw.vtx
new file mode 100644
index 000000000..953b5a647
Binary files /dev/null and b/models/fueltank/fueltank_1x2x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x2x1.vvd b/models/fueltank/fueltank_1x2x1.vvd
new file mode 100644
index 000000000..9616a190c
Binary files /dev/null and b/models/fueltank/fueltank_1x2x1.vvd differ
diff --git a/models/fueltank/fueltank_1x2x2.dx80.vtx b/models/fueltank/fueltank_1x2x2.dx80.vtx
new file mode 100644
index 000000000..dd4c9241d
Binary files /dev/null and b/models/fueltank/fueltank_1x2x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x2x2.dx90.vtx b/models/fueltank/fueltank_1x2x2.dx90.vtx
new file mode 100644
index 000000000..1a331aa94
Binary files /dev/null and b/models/fueltank/fueltank_1x2x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x2x2.mdl b/models/fueltank/fueltank_1x2x2.mdl
new file mode 100644
index 000000000..003324261
Binary files /dev/null and b/models/fueltank/fueltank_1x2x2.mdl differ
diff --git a/models/fueltank/fueltank_1x2x2.phy b/models/fueltank/fueltank_1x2x2.phy
new file mode 100644
index 000000000..b8c9e79c7
Binary files /dev/null and b/models/fueltank/fueltank_1x2x2.phy differ
diff --git a/models/fueltank/fueltank_1x2x2.sw.vtx b/models/fueltank/fueltank_1x2x2.sw.vtx
new file mode 100644
index 000000000..2b1659eb3
Binary files /dev/null and b/models/fueltank/fueltank_1x2x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x2x2.vvd b/models/fueltank/fueltank_1x2x2.vvd
new file mode 100644
index 000000000..97d3c1d33
Binary files /dev/null and b/models/fueltank/fueltank_1x2x2.vvd differ
diff --git a/models/fueltank/fueltank_1x2x4.dx80.vtx b/models/fueltank/fueltank_1x2x4.dx80.vtx
new file mode 100644
index 000000000..f85d49ba3
Binary files /dev/null and b/models/fueltank/fueltank_1x2x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x2x4.dx90.vtx b/models/fueltank/fueltank_1x2x4.dx90.vtx
new file mode 100644
index 000000000..a1a52044a
Binary files /dev/null and b/models/fueltank/fueltank_1x2x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x2x4.mdl b/models/fueltank/fueltank_1x2x4.mdl
new file mode 100644
index 000000000..ba84e5431
Binary files /dev/null and b/models/fueltank/fueltank_1x2x4.mdl differ
diff --git a/models/fueltank/fueltank_1x2x4.phy b/models/fueltank/fueltank_1x2x4.phy
new file mode 100644
index 000000000..6c405f938
Binary files /dev/null and b/models/fueltank/fueltank_1x2x4.phy differ
diff --git a/models/fueltank/fueltank_1x2x4.sw.vtx b/models/fueltank/fueltank_1x2x4.sw.vtx
new file mode 100644
index 000000000..67bafc0d2
Binary files /dev/null and b/models/fueltank/fueltank_1x2x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x2x4.vvd b/models/fueltank/fueltank_1x2x4.vvd
new file mode 100644
index 000000000..fcb86a6cb
Binary files /dev/null and b/models/fueltank/fueltank_1x2x4.vvd differ
diff --git a/models/fueltank/fueltank_1x4x1.dx80.vtx b/models/fueltank/fueltank_1x4x1.dx80.vtx
new file mode 100644
index 000000000..7a5e558a4
Binary files /dev/null and b/models/fueltank/fueltank_1x4x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x4x1.dx90.vtx b/models/fueltank/fueltank_1x4x1.dx90.vtx
new file mode 100644
index 000000000..b2f927723
Binary files /dev/null and b/models/fueltank/fueltank_1x4x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x4x1.mdl b/models/fueltank/fueltank_1x4x1.mdl
new file mode 100644
index 000000000..9109795c2
Binary files /dev/null and b/models/fueltank/fueltank_1x4x1.mdl differ
diff --git a/models/fueltank/fueltank_1x4x1.phy b/models/fueltank/fueltank_1x4x1.phy
new file mode 100644
index 000000000..974ac2ade
Binary files /dev/null and b/models/fueltank/fueltank_1x4x1.phy differ
diff --git a/models/fueltank/fueltank_1x4x1.sw.vtx b/models/fueltank/fueltank_1x4x1.sw.vtx
new file mode 100644
index 000000000..f951d62cc
Binary files /dev/null and b/models/fueltank/fueltank_1x4x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x4x1.vvd b/models/fueltank/fueltank_1x4x1.vvd
new file mode 100644
index 000000000..6bc2f1144
Binary files /dev/null and b/models/fueltank/fueltank_1x4x1.vvd differ
diff --git a/models/fueltank/fueltank_1x4x2.dx80.vtx b/models/fueltank/fueltank_1x4x2.dx80.vtx
new file mode 100644
index 000000000..52cb5e14b
Binary files /dev/null and b/models/fueltank/fueltank_1x4x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x4x2.dx90.vtx b/models/fueltank/fueltank_1x4x2.dx90.vtx
new file mode 100644
index 000000000..92e78bbba
Binary files /dev/null and b/models/fueltank/fueltank_1x4x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x4x2.mdl b/models/fueltank/fueltank_1x4x2.mdl
new file mode 100644
index 000000000..1024c47ce
Binary files /dev/null and b/models/fueltank/fueltank_1x4x2.mdl differ
diff --git a/models/fueltank/fueltank_1x4x2.phy b/models/fueltank/fueltank_1x4x2.phy
new file mode 100644
index 000000000..acaa0d4db
Binary files /dev/null and b/models/fueltank/fueltank_1x4x2.phy differ
diff --git a/models/fueltank/fueltank_1x4x2.sw.vtx b/models/fueltank/fueltank_1x4x2.sw.vtx
new file mode 100644
index 000000000..0dd848d1e
Binary files /dev/null and b/models/fueltank/fueltank_1x4x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x4x2.vvd b/models/fueltank/fueltank_1x4x2.vvd
new file mode 100644
index 000000000..bacbc7de8
Binary files /dev/null and b/models/fueltank/fueltank_1x4x2.vvd differ
diff --git a/models/fueltank/fueltank_1x4x4.dx80.vtx b/models/fueltank/fueltank_1x4x4.dx80.vtx
new file mode 100644
index 000000000..d3d32d7fe
Binary files /dev/null and b/models/fueltank/fueltank_1x4x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x4x4.dx90.vtx b/models/fueltank/fueltank_1x4x4.dx90.vtx
new file mode 100644
index 000000000..1662ceaae
Binary files /dev/null and b/models/fueltank/fueltank_1x4x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x4x4.mdl b/models/fueltank/fueltank_1x4x4.mdl
new file mode 100644
index 000000000..89cfa1cbc
Binary files /dev/null and b/models/fueltank/fueltank_1x4x4.mdl differ
diff --git a/models/fueltank/fueltank_1x4x4.phy b/models/fueltank/fueltank_1x4x4.phy
new file mode 100644
index 000000000..941e671a4
Binary files /dev/null and b/models/fueltank/fueltank_1x4x4.phy differ
diff --git a/models/fueltank/fueltank_1x4x4.sw.vtx b/models/fueltank/fueltank_1x4x4.sw.vtx
new file mode 100644
index 000000000..01254754c
Binary files /dev/null and b/models/fueltank/fueltank_1x4x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x4x4.vvd b/models/fueltank/fueltank_1x4x4.vvd
new file mode 100644
index 000000000..f47b087b8
Binary files /dev/null and b/models/fueltank/fueltank_1x4x4.vvd differ
diff --git a/models/fueltank/fueltank_1x6x1.dx80.vtx b/models/fueltank/fueltank_1x6x1.dx80.vtx
new file mode 100644
index 000000000..e68e65d0a
Binary files /dev/null and b/models/fueltank/fueltank_1x6x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x6x1.dx90.vtx b/models/fueltank/fueltank_1x6x1.dx90.vtx
new file mode 100644
index 000000000..c3a9dce88
Binary files /dev/null and b/models/fueltank/fueltank_1x6x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x6x1.mdl b/models/fueltank/fueltank_1x6x1.mdl
new file mode 100644
index 000000000..7903e51fd
Binary files /dev/null and b/models/fueltank/fueltank_1x6x1.mdl differ
diff --git a/models/fueltank/fueltank_1x6x1.phy b/models/fueltank/fueltank_1x6x1.phy
new file mode 100644
index 000000000..5887accac
Binary files /dev/null and b/models/fueltank/fueltank_1x6x1.phy differ
diff --git a/models/fueltank/fueltank_1x6x1.sw.vtx b/models/fueltank/fueltank_1x6x1.sw.vtx
new file mode 100644
index 000000000..4fd9aecca
Binary files /dev/null and b/models/fueltank/fueltank_1x6x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x6x1.vvd b/models/fueltank/fueltank_1x6x1.vvd
new file mode 100644
index 000000000..5e2405d36
Binary files /dev/null and b/models/fueltank/fueltank_1x6x1.vvd differ
diff --git a/models/fueltank/fueltank_1x6x2.dx80.vtx b/models/fueltank/fueltank_1x6x2.dx80.vtx
new file mode 100644
index 000000000..1c5324c23
Binary files /dev/null and b/models/fueltank/fueltank_1x6x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x6x2.dx90.vtx b/models/fueltank/fueltank_1x6x2.dx90.vtx
new file mode 100644
index 000000000..cbef5bb69
Binary files /dev/null and b/models/fueltank/fueltank_1x6x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x6x2.mdl b/models/fueltank/fueltank_1x6x2.mdl
new file mode 100644
index 000000000..f16f1c823
Binary files /dev/null and b/models/fueltank/fueltank_1x6x2.mdl differ
diff --git a/models/fueltank/fueltank_1x6x2.phy b/models/fueltank/fueltank_1x6x2.phy
new file mode 100644
index 000000000..66eeb3233
Binary files /dev/null and b/models/fueltank/fueltank_1x6x2.phy differ
diff --git a/models/fueltank/fueltank_1x6x2.sw.vtx b/models/fueltank/fueltank_1x6x2.sw.vtx
new file mode 100644
index 000000000..61bffc3ae
Binary files /dev/null and b/models/fueltank/fueltank_1x6x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x6x2.vvd b/models/fueltank/fueltank_1x6x2.vvd
new file mode 100644
index 000000000..45a16c158
Binary files /dev/null and b/models/fueltank/fueltank_1x6x2.vvd differ
diff --git a/models/fueltank/fueltank_1x6x4.dx80.vtx b/models/fueltank/fueltank_1x6x4.dx80.vtx
new file mode 100644
index 000000000..d2bbd4839
Binary files /dev/null and b/models/fueltank/fueltank_1x6x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x6x4.dx90.vtx b/models/fueltank/fueltank_1x6x4.dx90.vtx
new file mode 100644
index 000000000..3118c070a
Binary files /dev/null and b/models/fueltank/fueltank_1x6x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x6x4.mdl b/models/fueltank/fueltank_1x6x4.mdl
new file mode 100644
index 000000000..be43fb35f
Binary files /dev/null and b/models/fueltank/fueltank_1x6x4.mdl differ
diff --git a/models/fueltank/fueltank_1x6x4.phy b/models/fueltank/fueltank_1x6x4.phy
new file mode 100644
index 000000000..0bc17bf0f
Binary files /dev/null and b/models/fueltank/fueltank_1x6x4.phy differ
diff --git a/models/fueltank/fueltank_1x6x4.sw.vtx b/models/fueltank/fueltank_1x6x4.sw.vtx
new file mode 100644
index 000000000..f2cc3a5f2
Binary files /dev/null and b/models/fueltank/fueltank_1x6x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x6x4.vvd b/models/fueltank/fueltank_1x6x4.vvd
new file mode 100644
index 000000000..505af507f
Binary files /dev/null and b/models/fueltank/fueltank_1x6x4.vvd differ
diff --git a/models/fueltank/fueltank_1x8x1.dx80.vtx b/models/fueltank/fueltank_1x8x1.dx80.vtx
new file mode 100644
index 000000000..a30565a58
Binary files /dev/null and b/models/fueltank/fueltank_1x8x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x8x1.dx90.vtx b/models/fueltank/fueltank_1x8x1.dx90.vtx
new file mode 100644
index 000000000..13208ef14
Binary files /dev/null and b/models/fueltank/fueltank_1x8x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x8x1.mdl b/models/fueltank/fueltank_1x8x1.mdl
new file mode 100644
index 000000000..c1fb4101c
Binary files /dev/null and b/models/fueltank/fueltank_1x8x1.mdl differ
diff --git a/models/fueltank/fueltank_1x8x1.phy b/models/fueltank/fueltank_1x8x1.phy
new file mode 100644
index 000000000..891a6922c
Binary files /dev/null and b/models/fueltank/fueltank_1x8x1.phy differ
diff --git a/models/fueltank/fueltank_1x8x1.sw.vtx b/models/fueltank/fueltank_1x8x1.sw.vtx
new file mode 100644
index 000000000..6a19534ff
Binary files /dev/null and b/models/fueltank/fueltank_1x8x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x8x1.vvd b/models/fueltank/fueltank_1x8x1.vvd
new file mode 100644
index 000000000..39ba1deb3
Binary files /dev/null and b/models/fueltank/fueltank_1x8x1.vvd differ
diff --git a/models/fueltank/fueltank_1x8x2.dx80.vtx b/models/fueltank/fueltank_1x8x2.dx80.vtx
new file mode 100644
index 000000000..ca70c897b
Binary files /dev/null and b/models/fueltank/fueltank_1x8x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x8x2.dx90.vtx b/models/fueltank/fueltank_1x8x2.dx90.vtx
new file mode 100644
index 000000000..6dab969bb
Binary files /dev/null and b/models/fueltank/fueltank_1x8x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x8x2.mdl b/models/fueltank/fueltank_1x8x2.mdl
new file mode 100644
index 000000000..eb1def6c4
Binary files /dev/null and b/models/fueltank/fueltank_1x8x2.mdl differ
diff --git a/models/fueltank/fueltank_1x8x2.phy b/models/fueltank/fueltank_1x8x2.phy
new file mode 100644
index 000000000..fc9fc52ce
Binary files /dev/null and b/models/fueltank/fueltank_1x8x2.phy differ
diff --git a/models/fueltank/fueltank_1x8x2.sw.vtx b/models/fueltank/fueltank_1x8x2.sw.vtx
new file mode 100644
index 000000000..63cafeb29
Binary files /dev/null and b/models/fueltank/fueltank_1x8x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x8x2.vvd b/models/fueltank/fueltank_1x8x2.vvd
new file mode 100644
index 000000000..16cd4fcae
Binary files /dev/null and b/models/fueltank/fueltank_1x8x2.vvd differ
diff --git a/models/fueltank/fueltank_1x8x4.dx80.vtx b/models/fueltank/fueltank_1x8x4.dx80.vtx
new file mode 100644
index 000000000..a0acda200
Binary files /dev/null and b/models/fueltank/fueltank_1x8x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_1x8x4.dx90.vtx b/models/fueltank/fueltank_1x8x4.dx90.vtx
new file mode 100644
index 000000000..238b40f9f
Binary files /dev/null and b/models/fueltank/fueltank_1x8x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_1x8x4.mdl b/models/fueltank/fueltank_1x8x4.mdl
new file mode 100644
index 000000000..00113a6c7
Binary files /dev/null and b/models/fueltank/fueltank_1x8x4.mdl differ
diff --git a/models/fueltank/fueltank_1x8x4.phy b/models/fueltank/fueltank_1x8x4.phy
new file mode 100644
index 000000000..1b71dc999
Binary files /dev/null and b/models/fueltank/fueltank_1x8x4.phy differ
diff --git a/models/fueltank/fueltank_1x8x4.sw.vtx b/models/fueltank/fueltank_1x8x4.sw.vtx
new file mode 100644
index 000000000..4267075e6
Binary files /dev/null and b/models/fueltank/fueltank_1x8x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_1x8x4.vvd b/models/fueltank/fueltank_1x8x4.vvd
new file mode 100644
index 000000000..3b00e3b2f
Binary files /dev/null and b/models/fueltank/fueltank_1x8x4.vvd differ
diff --git a/models/fueltank/fueltank_2x2x1.dx80.vtx b/models/fueltank/fueltank_2x2x1.dx80.vtx
new file mode 100644
index 000000000..12ed7777b
Binary files /dev/null and b/models/fueltank/fueltank_2x2x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x2x1.dx90.vtx b/models/fueltank/fueltank_2x2x1.dx90.vtx
new file mode 100644
index 000000000..693c5ab1d
Binary files /dev/null and b/models/fueltank/fueltank_2x2x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x2x1.mdl b/models/fueltank/fueltank_2x2x1.mdl
new file mode 100644
index 000000000..3082fecdf
Binary files /dev/null and b/models/fueltank/fueltank_2x2x1.mdl differ
diff --git a/models/fueltank/fueltank_2x2x1.phy b/models/fueltank/fueltank_2x2x1.phy
new file mode 100644
index 000000000..633e936d6
Binary files /dev/null and b/models/fueltank/fueltank_2x2x1.phy differ
diff --git a/models/fueltank/fueltank_2x2x1.sw.vtx b/models/fueltank/fueltank_2x2x1.sw.vtx
new file mode 100644
index 000000000..ca2301da2
Binary files /dev/null and b/models/fueltank/fueltank_2x2x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x2x1.vvd b/models/fueltank/fueltank_2x2x1.vvd
new file mode 100644
index 000000000..a0b920d52
Binary files /dev/null and b/models/fueltank/fueltank_2x2x1.vvd differ
diff --git a/models/fueltank/fueltank_2x2x2.dx80.vtx b/models/fueltank/fueltank_2x2x2.dx80.vtx
new file mode 100644
index 000000000..3e11289cf
Binary files /dev/null and b/models/fueltank/fueltank_2x2x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x2x2.dx90.vtx b/models/fueltank/fueltank_2x2x2.dx90.vtx
new file mode 100644
index 000000000..6fd66c93b
Binary files /dev/null and b/models/fueltank/fueltank_2x2x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x2x2.mdl b/models/fueltank/fueltank_2x2x2.mdl
new file mode 100644
index 000000000..a00b6ed25
Binary files /dev/null and b/models/fueltank/fueltank_2x2x2.mdl differ
diff --git a/models/fueltank/fueltank_2x2x2.phy b/models/fueltank/fueltank_2x2x2.phy
new file mode 100644
index 000000000..0ccb760e0
Binary files /dev/null and b/models/fueltank/fueltank_2x2x2.phy differ
diff --git a/models/fueltank/fueltank_2x2x2.sw.vtx b/models/fueltank/fueltank_2x2x2.sw.vtx
new file mode 100644
index 000000000..b11de8802
Binary files /dev/null and b/models/fueltank/fueltank_2x2x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x2x2.vvd b/models/fueltank/fueltank_2x2x2.vvd
new file mode 100644
index 000000000..f1aa6bc33
Binary files /dev/null and b/models/fueltank/fueltank_2x2x2.vvd differ
diff --git a/models/fueltank/fueltank_2x2x4.dx80.vtx b/models/fueltank/fueltank_2x2x4.dx80.vtx
new file mode 100644
index 000000000..9325dc624
Binary files /dev/null and b/models/fueltank/fueltank_2x2x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x2x4.dx90.vtx b/models/fueltank/fueltank_2x2x4.dx90.vtx
new file mode 100644
index 000000000..08a81afea
Binary files /dev/null and b/models/fueltank/fueltank_2x2x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x2x4.mdl b/models/fueltank/fueltank_2x2x4.mdl
new file mode 100644
index 000000000..dd844f7a7
Binary files /dev/null and b/models/fueltank/fueltank_2x2x4.mdl differ
diff --git a/models/fueltank/fueltank_2x2x4.phy b/models/fueltank/fueltank_2x2x4.phy
new file mode 100644
index 000000000..bd7624cd8
Binary files /dev/null and b/models/fueltank/fueltank_2x2x4.phy differ
diff --git a/models/fueltank/fueltank_2x2x4.sw.vtx b/models/fueltank/fueltank_2x2x4.sw.vtx
new file mode 100644
index 000000000..7e994516d
Binary files /dev/null and b/models/fueltank/fueltank_2x2x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x2x4.vvd b/models/fueltank/fueltank_2x2x4.vvd
new file mode 100644
index 000000000..0b9db46bc
Binary files /dev/null and b/models/fueltank/fueltank_2x2x4.vvd differ
diff --git a/models/fueltank/fueltank_2x4x1.dx80.vtx b/models/fueltank/fueltank_2x4x1.dx80.vtx
new file mode 100644
index 000000000..97e72d3e1
Binary files /dev/null and b/models/fueltank/fueltank_2x4x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x4x1.dx90.vtx b/models/fueltank/fueltank_2x4x1.dx90.vtx
new file mode 100644
index 000000000..86fcdbd8a
Binary files /dev/null and b/models/fueltank/fueltank_2x4x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x4x1.mdl b/models/fueltank/fueltank_2x4x1.mdl
new file mode 100644
index 000000000..fecc7b546
Binary files /dev/null and b/models/fueltank/fueltank_2x4x1.mdl differ
diff --git a/models/fueltank/fueltank_2x4x1.phy b/models/fueltank/fueltank_2x4x1.phy
new file mode 100644
index 000000000..36b6f41d0
Binary files /dev/null and b/models/fueltank/fueltank_2x4x1.phy differ
diff --git a/models/fueltank/fueltank_2x4x1.sw.vtx b/models/fueltank/fueltank_2x4x1.sw.vtx
new file mode 100644
index 000000000..dbcfe2381
Binary files /dev/null and b/models/fueltank/fueltank_2x4x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x4x1.vvd b/models/fueltank/fueltank_2x4x1.vvd
new file mode 100644
index 000000000..e5abead3c
Binary files /dev/null and b/models/fueltank/fueltank_2x4x1.vvd differ
diff --git a/models/fueltank/fueltank_2x4x2.dx80.vtx b/models/fueltank/fueltank_2x4x2.dx80.vtx
new file mode 100644
index 000000000..c7fe7e780
Binary files /dev/null and b/models/fueltank/fueltank_2x4x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x4x2.dx90.vtx b/models/fueltank/fueltank_2x4x2.dx90.vtx
new file mode 100644
index 000000000..20e9d8106
Binary files /dev/null and b/models/fueltank/fueltank_2x4x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x4x2.mdl b/models/fueltank/fueltank_2x4x2.mdl
new file mode 100644
index 000000000..4b787acb3
Binary files /dev/null and b/models/fueltank/fueltank_2x4x2.mdl differ
diff --git a/models/fueltank/fueltank_2x4x2.phy b/models/fueltank/fueltank_2x4x2.phy
new file mode 100644
index 000000000..17ef4e00c
Binary files /dev/null and b/models/fueltank/fueltank_2x4x2.phy differ
diff --git a/models/fueltank/fueltank_2x4x2.sw.vtx b/models/fueltank/fueltank_2x4x2.sw.vtx
new file mode 100644
index 000000000..b65875ba1
Binary files /dev/null and b/models/fueltank/fueltank_2x4x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x4x2.vvd b/models/fueltank/fueltank_2x4x2.vvd
new file mode 100644
index 000000000..95f3902fd
Binary files /dev/null and b/models/fueltank/fueltank_2x4x2.vvd differ
diff --git a/models/fueltank/fueltank_2x4x4.dx80.vtx b/models/fueltank/fueltank_2x4x4.dx80.vtx
new file mode 100644
index 000000000..a63433d8a
Binary files /dev/null and b/models/fueltank/fueltank_2x4x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x4x4.dx90.vtx b/models/fueltank/fueltank_2x4x4.dx90.vtx
new file mode 100644
index 000000000..f5c537f7f
Binary files /dev/null and b/models/fueltank/fueltank_2x4x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x4x4.mdl b/models/fueltank/fueltank_2x4x4.mdl
new file mode 100644
index 000000000..cea599f1b
Binary files /dev/null and b/models/fueltank/fueltank_2x4x4.mdl differ
diff --git a/models/fueltank/fueltank_2x4x4.phy b/models/fueltank/fueltank_2x4x4.phy
new file mode 100644
index 000000000..a863e89b8
Binary files /dev/null and b/models/fueltank/fueltank_2x4x4.phy differ
diff --git a/models/fueltank/fueltank_2x4x4.sw.vtx b/models/fueltank/fueltank_2x4x4.sw.vtx
new file mode 100644
index 000000000..9743fff7b
Binary files /dev/null and b/models/fueltank/fueltank_2x4x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x4x4.vvd b/models/fueltank/fueltank_2x4x4.vvd
new file mode 100644
index 000000000..f5c79f683
Binary files /dev/null and b/models/fueltank/fueltank_2x4x4.vvd differ
diff --git a/models/fueltank/fueltank_2x6x1.dx80.vtx b/models/fueltank/fueltank_2x6x1.dx80.vtx
new file mode 100644
index 000000000..16c7f7b05
Binary files /dev/null and b/models/fueltank/fueltank_2x6x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x6x1.dx90.vtx b/models/fueltank/fueltank_2x6x1.dx90.vtx
new file mode 100644
index 000000000..8076b0d37
Binary files /dev/null and b/models/fueltank/fueltank_2x6x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x6x1.mdl b/models/fueltank/fueltank_2x6x1.mdl
new file mode 100644
index 000000000..6f3fefab4
Binary files /dev/null and b/models/fueltank/fueltank_2x6x1.mdl differ
diff --git a/models/fueltank/fueltank_2x6x1.phy b/models/fueltank/fueltank_2x6x1.phy
new file mode 100644
index 000000000..0a93881ec
Binary files /dev/null and b/models/fueltank/fueltank_2x6x1.phy differ
diff --git a/models/fueltank/fueltank_2x6x1.sw.vtx b/models/fueltank/fueltank_2x6x1.sw.vtx
new file mode 100644
index 000000000..29698863b
Binary files /dev/null and b/models/fueltank/fueltank_2x6x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x6x1.vvd b/models/fueltank/fueltank_2x6x1.vvd
new file mode 100644
index 000000000..33928f05f
Binary files /dev/null and b/models/fueltank/fueltank_2x6x1.vvd differ
diff --git a/models/fueltank/fueltank_2x6x2.dx80.vtx b/models/fueltank/fueltank_2x6x2.dx80.vtx
new file mode 100644
index 000000000..2c4f79b5c
Binary files /dev/null and b/models/fueltank/fueltank_2x6x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x6x2.dx90.vtx b/models/fueltank/fueltank_2x6x2.dx90.vtx
new file mode 100644
index 000000000..a5ab208f4
Binary files /dev/null and b/models/fueltank/fueltank_2x6x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x6x2.mdl b/models/fueltank/fueltank_2x6x2.mdl
new file mode 100644
index 000000000..7fd350101
Binary files /dev/null and b/models/fueltank/fueltank_2x6x2.mdl differ
diff --git a/models/fueltank/fueltank_2x6x2.phy b/models/fueltank/fueltank_2x6x2.phy
new file mode 100644
index 000000000..d41b296d2
Binary files /dev/null and b/models/fueltank/fueltank_2x6x2.phy differ
diff --git a/models/fueltank/fueltank_2x6x2.sw.vtx b/models/fueltank/fueltank_2x6x2.sw.vtx
new file mode 100644
index 000000000..3813a75a2
Binary files /dev/null and b/models/fueltank/fueltank_2x6x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x6x2.vvd b/models/fueltank/fueltank_2x6x2.vvd
new file mode 100644
index 000000000..dd7474b7c
Binary files /dev/null and b/models/fueltank/fueltank_2x6x2.vvd differ
diff --git a/models/fueltank/fueltank_2x6x4.dx80.vtx b/models/fueltank/fueltank_2x6x4.dx80.vtx
new file mode 100644
index 000000000..26952cc34
Binary files /dev/null and b/models/fueltank/fueltank_2x6x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x6x4.dx90.vtx b/models/fueltank/fueltank_2x6x4.dx90.vtx
new file mode 100644
index 000000000..d615879a2
Binary files /dev/null and b/models/fueltank/fueltank_2x6x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x6x4.mdl b/models/fueltank/fueltank_2x6x4.mdl
new file mode 100644
index 000000000..b4457cf51
Binary files /dev/null and b/models/fueltank/fueltank_2x6x4.mdl differ
diff --git a/models/fueltank/fueltank_2x6x4.phy b/models/fueltank/fueltank_2x6x4.phy
new file mode 100644
index 000000000..c25033019
Binary files /dev/null and b/models/fueltank/fueltank_2x6x4.phy differ
diff --git a/models/fueltank/fueltank_2x6x4.sw.vtx b/models/fueltank/fueltank_2x6x4.sw.vtx
new file mode 100644
index 000000000..1f3740703
Binary files /dev/null and b/models/fueltank/fueltank_2x6x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x6x4.vvd b/models/fueltank/fueltank_2x6x4.vvd
new file mode 100644
index 000000000..365cbdbb8
Binary files /dev/null and b/models/fueltank/fueltank_2x6x4.vvd differ
diff --git a/models/fueltank/fueltank_2x8x1.dx80.vtx b/models/fueltank/fueltank_2x8x1.dx80.vtx
new file mode 100644
index 000000000..f5b4e0aec
Binary files /dev/null and b/models/fueltank/fueltank_2x8x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x8x1.dx90.vtx b/models/fueltank/fueltank_2x8x1.dx90.vtx
new file mode 100644
index 000000000..7534ffeac
Binary files /dev/null and b/models/fueltank/fueltank_2x8x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x8x1.mdl b/models/fueltank/fueltank_2x8x1.mdl
new file mode 100644
index 000000000..27fccc097
Binary files /dev/null and b/models/fueltank/fueltank_2x8x1.mdl differ
diff --git a/models/fueltank/fueltank_2x8x1.phy b/models/fueltank/fueltank_2x8x1.phy
new file mode 100644
index 000000000..336139a45
Binary files /dev/null and b/models/fueltank/fueltank_2x8x1.phy differ
diff --git a/models/fueltank/fueltank_2x8x1.sw.vtx b/models/fueltank/fueltank_2x8x1.sw.vtx
new file mode 100644
index 000000000..544ca4cec
Binary files /dev/null and b/models/fueltank/fueltank_2x8x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x8x1.vvd b/models/fueltank/fueltank_2x8x1.vvd
new file mode 100644
index 000000000..447fe35ef
Binary files /dev/null and b/models/fueltank/fueltank_2x8x1.vvd differ
diff --git a/models/fueltank/fueltank_2x8x2.dx80.vtx b/models/fueltank/fueltank_2x8x2.dx80.vtx
new file mode 100644
index 000000000..fcef2d7f3
Binary files /dev/null and b/models/fueltank/fueltank_2x8x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x8x2.dx90.vtx b/models/fueltank/fueltank_2x8x2.dx90.vtx
new file mode 100644
index 000000000..21f0dcb38
Binary files /dev/null and b/models/fueltank/fueltank_2x8x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x8x2.mdl b/models/fueltank/fueltank_2x8x2.mdl
new file mode 100644
index 000000000..fc5698742
Binary files /dev/null and b/models/fueltank/fueltank_2x8x2.mdl differ
diff --git a/models/fueltank/fueltank_2x8x2.phy b/models/fueltank/fueltank_2x8x2.phy
new file mode 100644
index 000000000..58bb8fd79
Binary files /dev/null and b/models/fueltank/fueltank_2x8x2.phy differ
diff --git a/models/fueltank/fueltank_2x8x2.sw.vtx b/models/fueltank/fueltank_2x8x2.sw.vtx
new file mode 100644
index 000000000..7684ea478
Binary files /dev/null and b/models/fueltank/fueltank_2x8x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x8x2.vvd b/models/fueltank/fueltank_2x8x2.vvd
new file mode 100644
index 000000000..c825d3945
Binary files /dev/null and b/models/fueltank/fueltank_2x8x2.vvd differ
diff --git a/models/fueltank/fueltank_2x8x4.dx80.vtx b/models/fueltank/fueltank_2x8x4.dx80.vtx
new file mode 100644
index 000000000..d9bd8a6cb
Binary files /dev/null and b/models/fueltank/fueltank_2x8x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_2x8x4.dx90.vtx b/models/fueltank/fueltank_2x8x4.dx90.vtx
new file mode 100644
index 000000000..4a7d80e7b
Binary files /dev/null and b/models/fueltank/fueltank_2x8x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_2x8x4.mdl b/models/fueltank/fueltank_2x8x4.mdl
new file mode 100644
index 000000000..4dca5b707
Binary files /dev/null and b/models/fueltank/fueltank_2x8x4.mdl differ
diff --git a/models/fueltank/fueltank_2x8x4.phy b/models/fueltank/fueltank_2x8x4.phy
new file mode 100644
index 000000000..42a54a97c
Binary files /dev/null and b/models/fueltank/fueltank_2x8x4.phy differ
diff --git a/models/fueltank/fueltank_2x8x4.sw.vtx b/models/fueltank/fueltank_2x8x4.sw.vtx
new file mode 100644
index 000000000..ebbdd797f
Binary files /dev/null and b/models/fueltank/fueltank_2x8x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_2x8x4.vvd b/models/fueltank/fueltank_2x8x4.vvd
new file mode 100644
index 000000000..959e71c6e
Binary files /dev/null and b/models/fueltank/fueltank_2x8x4.vvd differ
diff --git a/models/fueltank/fueltank_4x4x1.dx80.vtx b/models/fueltank/fueltank_4x4x1.dx80.vtx
new file mode 100644
index 000000000..6ea985e36
Binary files /dev/null and b/models/fueltank/fueltank_4x4x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x4x1.dx90.vtx b/models/fueltank/fueltank_4x4x1.dx90.vtx
new file mode 100644
index 000000000..b3205e465
Binary files /dev/null and b/models/fueltank/fueltank_4x4x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x4x1.mdl b/models/fueltank/fueltank_4x4x1.mdl
new file mode 100644
index 000000000..1acf3fe74
Binary files /dev/null and b/models/fueltank/fueltank_4x4x1.mdl differ
diff --git a/models/fueltank/fueltank_4x4x1.phy b/models/fueltank/fueltank_4x4x1.phy
new file mode 100644
index 000000000..16a7605a0
Binary files /dev/null and b/models/fueltank/fueltank_4x4x1.phy differ
diff --git a/models/fueltank/fueltank_4x4x1.sw.vtx b/models/fueltank/fueltank_4x4x1.sw.vtx
new file mode 100644
index 000000000..608fd4065
Binary files /dev/null and b/models/fueltank/fueltank_4x4x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x4x1.vvd b/models/fueltank/fueltank_4x4x1.vvd
new file mode 100644
index 000000000..cf94f4f04
Binary files /dev/null and b/models/fueltank/fueltank_4x4x1.vvd differ
diff --git a/models/fueltank/fueltank_4x4x2.dx80.vtx b/models/fueltank/fueltank_4x4x2.dx80.vtx
new file mode 100644
index 000000000..d3aa00f51
Binary files /dev/null and b/models/fueltank/fueltank_4x4x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x4x2.dx90.vtx b/models/fueltank/fueltank_4x4x2.dx90.vtx
new file mode 100644
index 000000000..fedf3be76
Binary files /dev/null and b/models/fueltank/fueltank_4x4x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x4x2.mdl b/models/fueltank/fueltank_4x4x2.mdl
new file mode 100644
index 000000000..05ce07367
Binary files /dev/null and b/models/fueltank/fueltank_4x4x2.mdl differ
diff --git a/models/fueltank/fueltank_4x4x2.phy b/models/fueltank/fueltank_4x4x2.phy
new file mode 100644
index 000000000..f4bb2e6d3
Binary files /dev/null and b/models/fueltank/fueltank_4x4x2.phy differ
diff --git a/models/fueltank/fueltank_4x4x2.sw.vtx b/models/fueltank/fueltank_4x4x2.sw.vtx
new file mode 100644
index 000000000..2e814d603
Binary files /dev/null and b/models/fueltank/fueltank_4x4x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x4x2.vvd b/models/fueltank/fueltank_4x4x2.vvd
new file mode 100644
index 000000000..118d72752
Binary files /dev/null and b/models/fueltank/fueltank_4x4x2.vvd differ
diff --git a/models/fueltank/fueltank_4x4x4.dx80.vtx b/models/fueltank/fueltank_4x4x4.dx80.vtx
new file mode 100644
index 000000000..cdad371df
Binary files /dev/null and b/models/fueltank/fueltank_4x4x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x4x4.dx90.vtx b/models/fueltank/fueltank_4x4x4.dx90.vtx
new file mode 100644
index 000000000..578bcf007
Binary files /dev/null and b/models/fueltank/fueltank_4x4x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x4x4.mdl b/models/fueltank/fueltank_4x4x4.mdl
new file mode 100644
index 000000000..ed566822c
Binary files /dev/null and b/models/fueltank/fueltank_4x4x4.mdl differ
diff --git a/models/fueltank/fueltank_4x4x4.phy b/models/fueltank/fueltank_4x4x4.phy
new file mode 100644
index 000000000..7cf626d89
Binary files /dev/null and b/models/fueltank/fueltank_4x4x4.phy differ
diff --git a/models/fueltank/fueltank_4x4x4.sw.vtx b/models/fueltank/fueltank_4x4x4.sw.vtx
new file mode 100644
index 000000000..a5b2c897d
Binary files /dev/null and b/models/fueltank/fueltank_4x4x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x4x4.vvd b/models/fueltank/fueltank_4x4x4.vvd
new file mode 100644
index 000000000..beae99a7d
Binary files /dev/null and b/models/fueltank/fueltank_4x4x4.vvd differ
diff --git a/models/fueltank/fueltank_4x6x1.dx80.vtx b/models/fueltank/fueltank_4x6x1.dx80.vtx
new file mode 100644
index 000000000..ea7db3c71
Binary files /dev/null and b/models/fueltank/fueltank_4x6x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x6x1.dx90.vtx b/models/fueltank/fueltank_4x6x1.dx90.vtx
new file mode 100644
index 000000000..547295be6
Binary files /dev/null and b/models/fueltank/fueltank_4x6x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x6x1.mdl b/models/fueltank/fueltank_4x6x1.mdl
new file mode 100644
index 000000000..6271abb9e
Binary files /dev/null and b/models/fueltank/fueltank_4x6x1.mdl differ
diff --git a/models/fueltank/fueltank_4x6x1.phy b/models/fueltank/fueltank_4x6x1.phy
new file mode 100644
index 000000000..181fc9448
Binary files /dev/null and b/models/fueltank/fueltank_4x6x1.phy differ
diff --git a/models/fueltank/fueltank_4x6x1.sw.vtx b/models/fueltank/fueltank_4x6x1.sw.vtx
new file mode 100644
index 000000000..cdb373d3d
Binary files /dev/null and b/models/fueltank/fueltank_4x6x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x6x1.vvd b/models/fueltank/fueltank_4x6x1.vvd
new file mode 100644
index 000000000..7d0b5f0f7
Binary files /dev/null and b/models/fueltank/fueltank_4x6x1.vvd differ
diff --git a/models/fueltank/fueltank_4x6x2.dx80.vtx b/models/fueltank/fueltank_4x6x2.dx80.vtx
new file mode 100644
index 000000000..fdb574d13
Binary files /dev/null and b/models/fueltank/fueltank_4x6x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x6x2.dx90.vtx b/models/fueltank/fueltank_4x6x2.dx90.vtx
new file mode 100644
index 000000000..20aa33814
Binary files /dev/null and b/models/fueltank/fueltank_4x6x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x6x2.mdl b/models/fueltank/fueltank_4x6x2.mdl
new file mode 100644
index 000000000..a5dce202d
Binary files /dev/null and b/models/fueltank/fueltank_4x6x2.mdl differ
diff --git a/models/fueltank/fueltank_4x6x2.phy b/models/fueltank/fueltank_4x6x2.phy
new file mode 100644
index 000000000..099a355aa
Binary files /dev/null and b/models/fueltank/fueltank_4x6x2.phy differ
diff --git a/models/fueltank/fueltank_4x6x2.sw.vtx b/models/fueltank/fueltank_4x6x2.sw.vtx
new file mode 100644
index 000000000..d2c5a7549
Binary files /dev/null and b/models/fueltank/fueltank_4x6x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x6x2.vvd b/models/fueltank/fueltank_4x6x2.vvd
new file mode 100644
index 000000000..e9ec5ebf3
Binary files /dev/null and b/models/fueltank/fueltank_4x6x2.vvd differ
diff --git a/models/fueltank/fueltank_4x6x4.dx80.vtx b/models/fueltank/fueltank_4x6x4.dx80.vtx
new file mode 100644
index 000000000..d9a19bb11
Binary files /dev/null and b/models/fueltank/fueltank_4x6x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x6x4.dx90.vtx b/models/fueltank/fueltank_4x6x4.dx90.vtx
new file mode 100644
index 000000000..65b4342a4
Binary files /dev/null and b/models/fueltank/fueltank_4x6x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x6x4.mdl b/models/fueltank/fueltank_4x6x4.mdl
new file mode 100644
index 000000000..e9dd5f943
Binary files /dev/null and b/models/fueltank/fueltank_4x6x4.mdl differ
diff --git a/models/fueltank/fueltank_4x6x4.phy b/models/fueltank/fueltank_4x6x4.phy
new file mode 100644
index 000000000..cb2fd12a3
Binary files /dev/null and b/models/fueltank/fueltank_4x6x4.phy differ
diff --git a/models/fueltank/fueltank_4x6x4.sw.vtx b/models/fueltank/fueltank_4x6x4.sw.vtx
new file mode 100644
index 000000000..196ee9703
Binary files /dev/null and b/models/fueltank/fueltank_4x6x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x6x4.vvd b/models/fueltank/fueltank_4x6x4.vvd
new file mode 100644
index 000000000..06376bfaf
Binary files /dev/null and b/models/fueltank/fueltank_4x6x4.vvd differ
diff --git a/models/fueltank/fueltank_4x8x1.dx80.vtx b/models/fueltank/fueltank_4x8x1.dx80.vtx
new file mode 100644
index 000000000..ea8cf1d17
Binary files /dev/null and b/models/fueltank/fueltank_4x8x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x8x1.dx90.vtx b/models/fueltank/fueltank_4x8x1.dx90.vtx
new file mode 100644
index 000000000..c07395cd1
Binary files /dev/null and b/models/fueltank/fueltank_4x8x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x8x1.mdl b/models/fueltank/fueltank_4x8x1.mdl
new file mode 100644
index 000000000..52ae8193c
Binary files /dev/null and b/models/fueltank/fueltank_4x8x1.mdl differ
diff --git a/models/fueltank/fueltank_4x8x1.phy b/models/fueltank/fueltank_4x8x1.phy
new file mode 100644
index 000000000..10259b826
Binary files /dev/null and b/models/fueltank/fueltank_4x8x1.phy differ
diff --git a/models/fueltank/fueltank_4x8x1.sw.vtx b/models/fueltank/fueltank_4x8x1.sw.vtx
new file mode 100644
index 000000000..139ec0295
Binary files /dev/null and b/models/fueltank/fueltank_4x8x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x8x1.vvd b/models/fueltank/fueltank_4x8x1.vvd
new file mode 100644
index 000000000..ce6e6445f
Binary files /dev/null and b/models/fueltank/fueltank_4x8x1.vvd differ
diff --git a/models/fueltank/fueltank_4x8x2.dx80.vtx b/models/fueltank/fueltank_4x8x2.dx80.vtx
new file mode 100644
index 000000000..ce5011e63
Binary files /dev/null and b/models/fueltank/fueltank_4x8x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x8x2.dx90.vtx b/models/fueltank/fueltank_4x8x2.dx90.vtx
new file mode 100644
index 000000000..a177bb475
Binary files /dev/null and b/models/fueltank/fueltank_4x8x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x8x2.mdl b/models/fueltank/fueltank_4x8x2.mdl
new file mode 100644
index 000000000..c28f03f63
Binary files /dev/null and b/models/fueltank/fueltank_4x8x2.mdl differ
diff --git a/models/fueltank/fueltank_4x8x2.phy b/models/fueltank/fueltank_4x8x2.phy
new file mode 100644
index 000000000..944679a94
Binary files /dev/null and b/models/fueltank/fueltank_4x8x2.phy differ
diff --git a/models/fueltank/fueltank_4x8x2.sw.vtx b/models/fueltank/fueltank_4x8x2.sw.vtx
new file mode 100644
index 000000000..338b2bc06
Binary files /dev/null and b/models/fueltank/fueltank_4x8x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x8x2.vvd b/models/fueltank/fueltank_4x8x2.vvd
new file mode 100644
index 000000000..775e1ee22
Binary files /dev/null and b/models/fueltank/fueltank_4x8x2.vvd differ
diff --git a/models/fueltank/fueltank_4x8x4.dx80.vtx b/models/fueltank/fueltank_4x8x4.dx80.vtx
new file mode 100644
index 000000000..7af90ebae
Binary files /dev/null and b/models/fueltank/fueltank_4x8x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_4x8x4.dx90.vtx b/models/fueltank/fueltank_4x8x4.dx90.vtx
new file mode 100644
index 000000000..6a02413df
Binary files /dev/null and b/models/fueltank/fueltank_4x8x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_4x8x4.mdl b/models/fueltank/fueltank_4x8x4.mdl
new file mode 100644
index 000000000..b2dc9c34c
Binary files /dev/null and b/models/fueltank/fueltank_4x8x4.mdl differ
diff --git a/models/fueltank/fueltank_4x8x4.phy b/models/fueltank/fueltank_4x8x4.phy
new file mode 100644
index 000000000..5c1719b3f
Binary files /dev/null and b/models/fueltank/fueltank_4x8x4.phy differ
diff --git a/models/fueltank/fueltank_4x8x4.sw.vtx b/models/fueltank/fueltank_4x8x4.sw.vtx
new file mode 100644
index 000000000..a39a32270
Binary files /dev/null and b/models/fueltank/fueltank_4x8x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_4x8x4.vvd b/models/fueltank/fueltank_4x8x4.vvd
new file mode 100644
index 000000000..039f72ee1
Binary files /dev/null and b/models/fueltank/fueltank_4x8x4.vvd differ
diff --git a/models/fueltank/fueltank_6x6x1.dx80.vtx b/models/fueltank/fueltank_6x6x1.dx80.vtx
new file mode 100644
index 000000000..0be2643d5
Binary files /dev/null and b/models/fueltank/fueltank_6x6x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_6x6x1.dx90.vtx b/models/fueltank/fueltank_6x6x1.dx90.vtx
new file mode 100644
index 000000000..1b383b4a8
Binary files /dev/null and b/models/fueltank/fueltank_6x6x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_6x6x1.mdl b/models/fueltank/fueltank_6x6x1.mdl
new file mode 100644
index 000000000..87158c3cc
Binary files /dev/null and b/models/fueltank/fueltank_6x6x1.mdl differ
diff --git a/models/fueltank/fueltank_6x6x1.phy b/models/fueltank/fueltank_6x6x1.phy
new file mode 100644
index 000000000..ef8068b72
Binary files /dev/null and b/models/fueltank/fueltank_6x6x1.phy differ
diff --git a/models/fueltank/fueltank_6x6x1.sw.vtx b/models/fueltank/fueltank_6x6x1.sw.vtx
new file mode 100644
index 000000000..d612011aa
Binary files /dev/null and b/models/fueltank/fueltank_6x6x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_6x6x1.vvd b/models/fueltank/fueltank_6x6x1.vvd
new file mode 100644
index 000000000..81f0d2797
Binary files /dev/null and b/models/fueltank/fueltank_6x6x1.vvd differ
diff --git a/models/fueltank/fueltank_6x6x2.dx80.vtx b/models/fueltank/fueltank_6x6x2.dx80.vtx
new file mode 100644
index 000000000..ec192787f
Binary files /dev/null and b/models/fueltank/fueltank_6x6x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_6x6x2.dx90.vtx b/models/fueltank/fueltank_6x6x2.dx90.vtx
new file mode 100644
index 000000000..2066ef3c7
Binary files /dev/null and b/models/fueltank/fueltank_6x6x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_6x6x2.mdl b/models/fueltank/fueltank_6x6x2.mdl
new file mode 100644
index 000000000..bb9f0fddf
Binary files /dev/null and b/models/fueltank/fueltank_6x6x2.mdl differ
diff --git a/models/fueltank/fueltank_6x6x2.phy b/models/fueltank/fueltank_6x6x2.phy
new file mode 100644
index 000000000..75a9f5814
Binary files /dev/null and b/models/fueltank/fueltank_6x6x2.phy differ
diff --git a/models/fueltank/fueltank_6x6x2.sw.vtx b/models/fueltank/fueltank_6x6x2.sw.vtx
new file mode 100644
index 000000000..30bae4d2d
Binary files /dev/null and b/models/fueltank/fueltank_6x6x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_6x6x2.vvd b/models/fueltank/fueltank_6x6x2.vvd
new file mode 100644
index 000000000..3f74d3fde
Binary files /dev/null and b/models/fueltank/fueltank_6x6x2.vvd differ
diff --git a/models/fueltank/fueltank_6x6x4.dx80.vtx b/models/fueltank/fueltank_6x6x4.dx80.vtx
new file mode 100644
index 000000000..bb049910f
Binary files /dev/null and b/models/fueltank/fueltank_6x6x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_6x6x4.dx90.vtx b/models/fueltank/fueltank_6x6x4.dx90.vtx
new file mode 100644
index 000000000..55e3e97a7
Binary files /dev/null and b/models/fueltank/fueltank_6x6x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_6x6x4.mdl b/models/fueltank/fueltank_6x6x4.mdl
new file mode 100644
index 000000000..bd4e680aa
Binary files /dev/null and b/models/fueltank/fueltank_6x6x4.mdl differ
diff --git a/models/fueltank/fueltank_6x6x4.phy b/models/fueltank/fueltank_6x6x4.phy
new file mode 100644
index 000000000..e20cd832a
Binary files /dev/null and b/models/fueltank/fueltank_6x6x4.phy differ
diff --git a/models/fueltank/fueltank_6x6x4.sw.vtx b/models/fueltank/fueltank_6x6x4.sw.vtx
new file mode 100644
index 000000000..282a89e26
Binary files /dev/null and b/models/fueltank/fueltank_6x6x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_6x6x4.vvd b/models/fueltank/fueltank_6x6x4.vvd
new file mode 100644
index 000000000..7627a21f7
Binary files /dev/null and b/models/fueltank/fueltank_6x6x4.vvd differ
diff --git a/models/fueltank/fueltank_6x8x1.dx80.vtx b/models/fueltank/fueltank_6x8x1.dx80.vtx
new file mode 100644
index 000000000..3da5fd345
Binary files /dev/null and b/models/fueltank/fueltank_6x8x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_6x8x1.dx90.vtx b/models/fueltank/fueltank_6x8x1.dx90.vtx
new file mode 100644
index 000000000..4675283e2
Binary files /dev/null and b/models/fueltank/fueltank_6x8x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_6x8x1.mdl b/models/fueltank/fueltank_6x8x1.mdl
new file mode 100644
index 000000000..0059e9765
Binary files /dev/null and b/models/fueltank/fueltank_6x8x1.mdl differ
diff --git a/models/fueltank/fueltank_6x8x1.phy b/models/fueltank/fueltank_6x8x1.phy
new file mode 100644
index 000000000..0ef20ee41
Binary files /dev/null and b/models/fueltank/fueltank_6x8x1.phy differ
diff --git a/models/fueltank/fueltank_6x8x1.sw.vtx b/models/fueltank/fueltank_6x8x1.sw.vtx
new file mode 100644
index 000000000..2fbdbc776
Binary files /dev/null and b/models/fueltank/fueltank_6x8x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_6x8x1.vvd b/models/fueltank/fueltank_6x8x1.vvd
new file mode 100644
index 000000000..3ed6fb624
Binary files /dev/null and b/models/fueltank/fueltank_6x8x1.vvd differ
diff --git a/models/fueltank/fueltank_6x8x2.dx80.vtx b/models/fueltank/fueltank_6x8x2.dx80.vtx
new file mode 100644
index 000000000..ab029d3f8
Binary files /dev/null and b/models/fueltank/fueltank_6x8x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_6x8x2.dx90.vtx b/models/fueltank/fueltank_6x8x2.dx90.vtx
new file mode 100644
index 000000000..45e72c316
Binary files /dev/null and b/models/fueltank/fueltank_6x8x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_6x8x2.mdl b/models/fueltank/fueltank_6x8x2.mdl
new file mode 100644
index 000000000..152ceb6e6
Binary files /dev/null and b/models/fueltank/fueltank_6x8x2.mdl differ
diff --git a/models/fueltank/fueltank_6x8x2.phy b/models/fueltank/fueltank_6x8x2.phy
new file mode 100644
index 000000000..22a3a663d
Binary files /dev/null and b/models/fueltank/fueltank_6x8x2.phy differ
diff --git a/models/fueltank/fueltank_6x8x2.sw.vtx b/models/fueltank/fueltank_6x8x2.sw.vtx
new file mode 100644
index 000000000..936a73b1f
Binary files /dev/null and b/models/fueltank/fueltank_6x8x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_6x8x2.vvd b/models/fueltank/fueltank_6x8x2.vvd
new file mode 100644
index 000000000..1088707b8
Binary files /dev/null and b/models/fueltank/fueltank_6x8x2.vvd differ
diff --git a/models/fueltank/fueltank_6x8x4.dx80.vtx b/models/fueltank/fueltank_6x8x4.dx80.vtx
new file mode 100644
index 000000000..d174ff293
Binary files /dev/null and b/models/fueltank/fueltank_6x8x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_6x8x4.dx90.vtx b/models/fueltank/fueltank_6x8x4.dx90.vtx
new file mode 100644
index 000000000..7286cf14d
Binary files /dev/null and b/models/fueltank/fueltank_6x8x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_6x8x4.mdl b/models/fueltank/fueltank_6x8x4.mdl
new file mode 100644
index 000000000..8239f3d16
Binary files /dev/null and b/models/fueltank/fueltank_6x8x4.mdl differ
diff --git a/models/fueltank/fueltank_6x8x4.phy b/models/fueltank/fueltank_6x8x4.phy
new file mode 100644
index 000000000..f25ca64b4
Binary files /dev/null and b/models/fueltank/fueltank_6x8x4.phy differ
diff --git a/models/fueltank/fueltank_6x8x4.sw.vtx b/models/fueltank/fueltank_6x8x4.sw.vtx
new file mode 100644
index 000000000..5f75f12a5
Binary files /dev/null and b/models/fueltank/fueltank_6x8x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_6x8x4.vvd b/models/fueltank/fueltank_6x8x4.vvd
new file mode 100644
index 000000000..2310a9cce
Binary files /dev/null and b/models/fueltank/fueltank_6x8x4.vvd differ
diff --git a/models/fueltank/fueltank_8x8x1.dx80.vtx b/models/fueltank/fueltank_8x8x1.dx80.vtx
new file mode 100644
index 000000000..daff210bd
Binary files /dev/null and b/models/fueltank/fueltank_8x8x1.dx80.vtx differ
diff --git a/models/fueltank/fueltank_8x8x1.dx90.vtx b/models/fueltank/fueltank_8x8x1.dx90.vtx
new file mode 100644
index 000000000..d8c2029e2
Binary files /dev/null and b/models/fueltank/fueltank_8x8x1.dx90.vtx differ
diff --git a/models/fueltank/fueltank_8x8x1.mdl b/models/fueltank/fueltank_8x8x1.mdl
new file mode 100644
index 000000000..bd4aa14c0
Binary files /dev/null and b/models/fueltank/fueltank_8x8x1.mdl differ
diff --git a/models/fueltank/fueltank_8x8x1.phy b/models/fueltank/fueltank_8x8x1.phy
new file mode 100644
index 000000000..ebe524f1d
Binary files /dev/null and b/models/fueltank/fueltank_8x8x1.phy differ
diff --git a/models/fueltank/fueltank_8x8x1.sw.vtx b/models/fueltank/fueltank_8x8x1.sw.vtx
new file mode 100644
index 000000000..561d89bdd
Binary files /dev/null and b/models/fueltank/fueltank_8x8x1.sw.vtx differ
diff --git a/models/fueltank/fueltank_8x8x1.vvd b/models/fueltank/fueltank_8x8x1.vvd
new file mode 100644
index 000000000..4ce5237b6
Binary files /dev/null and b/models/fueltank/fueltank_8x8x1.vvd differ
diff --git a/models/fueltank/fueltank_8x8x2.dx80.vtx b/models/fueltank/fueltank_8x8x2.dx80.vtx
new file mode 100644
index 000000000..037217fc9
Binary files /dev/null and b/models/fueltank/fueltank_8x8x2.dx80.vtx differ
diff --git a/models/fueltank/fueltank_8x8x2.dx90.vtx b/models/fueltank/fueltank_8x8x2.dx90.vtx
new file mode 100644
index 000000000..ef8b881ff
Binary files /dev/null and b/models/fueltank/fueltank_8x8x2.dx90.vtx differ
diff --git a/models/fueltank/fueltank_8x8x2.mdl b/models/fueltank/fueltank_8x8x2.mdl
new file mode 100644
index 000000000..d8bc30e41
Binary files /dev/null and b/models/fueltank/fueltank_8x8x2.mdl differ
diff --git a/models/fueltank/fueltank_8x8x2.phy b/models/fueltank/fueltank_8x8x2.phy
new file mode 100644
index 000000000..e12c02b71
Binary files /dev/null and b/models/fueltank/fueltank_8x8x2.phy differ
diff --git a/models/fueltank/fueltank_8x8x2.sw.vtx b/models/fueltank/fueltank_8x8x2.sw.vtx
new file mode 100644
index 000000000..73020b53f
Binary files /dev/null and b/models/fueltank/fueltank_8x8x2.sw.vtx differ
diff --git a/models/fueltank/fueltank_8x8x2.vvd b/models/fueltank/fueltank_8x8x2.vvd
new file mode 100644
index 000000000..78f2da9a3
Binary files /dev/null and b/models/fueltank/fueltank_8x8x2.vvd differ
diff --git a/models/fueltank/fueltank_8x8x4.dx80.vtx b/models/fueltank/fueltank_8x8x4.dx80.vtx
new file mode 100644
index 000000000..d28d8ea29
Binary files /dev/null and b/models/fueltank/fueltank_8x8x4.dx80.vtx differ
diff --git a/models/fueltank/fueltank_8x8x4.dx90.vtx b/models/fueltank/fueltank_8x8x4.dx90.vtx
new file mode 100644
index 000000000..be3a6b4a3
Binary files /dev/null and b/models/fueltank/fueltank_8x8x4.dx90.vtx differ
diff --git a/models/fueltank/fueltank_8x8x4.mdl b/models/fueltank/fueltank_8x8x4.mdl
new file mode 100644
index 000000000..2ef60c7a5
Binary files /dev/null and b/models/fueltank/fueltank_8x8x4.mdl differ
diff --git a/models/fueltank/fueltank_8x8x4.phy b/models/fueltank/fueltank_8x8x4.phy
new file mode 100644
index 000000000..9620172db
Binary files /dev/null and b/models/fueltank/fueltank_8x8x4.phy differ
diff --git a/models/fueltank/fueltank_8x8x4.sw.vtx b/models/fueltank/fueltank_8x8x4.sw.vtx
new file mode 100644
index 000000000..716a4ce64
Binary files /dev/null and b/models/fueltank/fueltank_8x8x4.sw.vtx differ
diff --git a/models/fueltank/fueltank_8x8x4.vvd b/models/fueltank/fueltank_8x8x4.vvd
new file mode 100644
index 000000000..a34099da5
Binary files /dev/null and b/models/fueltank/fueltank_8x8x4.vvd differ
diff --git a/models/howitzer/howitzer_105mm.dx80.vtx b/models/howitzer/howitzer_105mm.dx80.vtx
index d7dc880cb..49d578272 100644
Binary files a/models/howitzer/howitzer_105mm.dx80.vtx and b/models/howitzer/howitzer_105mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_105mm.dx90.vtx b/models/howitzer/howitzer_105mm.dx90.vtx
index fed2afd04..15b85c5d2 100644
Binary files a/models/howitzer/howitzer_105mm.dx90.vtx and b/models/howitzer/howitzer_105mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_105mm.mdl b/models/howitzer/howitzer_105mm.mdl
index 1b3397a59..c4619cc10 100644
Binary files a/models/howitzer/howitzer_105mm.mdl and b/models/howitzer/howitzer_105mm.mdl differ
diff --git a/models/howitzer/howitzer_105mm.phy b/models/howitzer/howitzer_105mm.phy
index 512149d49..602bf4938 100644
Binary files a/models/howitzer/howitzer_105mm.phy and b/models/howitzer/howitzer_105mm.phy differ
diff --git a/models/howitzer/howitzer_105mm.sw.vtx b/models/howitzer/howitzer_105mm.sw.vtx
index 75e4321f8..1cd2edf13 100644
Binary files a/models/howitzer/howitzer_105mm.sw.vtx and b/models/howitzer/howitzer_105mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_105mm.vvd b/models/howitzer/howitzer_105mm.vvd
index 5394102a5..8462ba5e1 100644
Binary files a/models/howitzer/howitzer_105mm.vvd and b/models/howitzer/howitzer_105mm.vvd differ
diff --git a/models/howitzer/howitzer_122mm.dx80.vtx b/models/howitzer/howitzer_122mm.dx80.vtx
new file mode 100644
index 000000000..cca0d88d8
Binary files /dev/null and b/models/howitzer/howitzer_122mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_122mm.dx90.vtx b/models/howitzer/howitzer_122mm.dx90.vtx
new file mode 100644
index 000000000..7e9319562
Binary files /dev/null and b/models/howitzer/howitzer_122mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_122mm.mdl b/models/howitzer/howitzer_122mm.mdl
new file mode 100644
index 000000000..7dcea4a03
Binary files /dev/null and b/models/howitzer/howitzer_122mm.mdl differ
diff --git a/models/howitzer/howitzer_122mm.phy b/models/howitzer/howitzer_122mm.phy
new file mode 100644
index 000000000..76736e9c2
Binary files /dev/null and b/models/howitzer/howitzer_122mm.phy differ
diff --git a/models/howitzer/howitzer_122mm.sw.vtx b/models/howitzer/howitzer_122mm.sw.vtx
new file mode 100644
index 000000000..dff5122ba
Binary files /dev/null and b/models/howitzer/howitzer_122mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_122mm.vvd b/models/howitzer/howitzer_122mm.vvd
new file mode 100644
index 000000000..2186e945f
Binary files /dev/null and b/models/howitzer/howitzer_122mm.vvd differ
diff --git a/models/howitzer/howitzer_155mm.dx80.vtx b/models/howitzer/howitzer_155mm.dx80.vtx
index 8e34ea97e..0a5ead0ca 100644
Binary files a/models/howitzer/howitzer_155mm.dx80.vtx and b/models/howitzer/howitzer_155mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_155mm.dx90.vtx b/models/howitzer/howitzer_155mm.dx90.vtx
index a8ace43ec..e082d9358 100644
Binary files a/models/howitzer/howitzer_155mm.dx90.vtx and b/models/howitzer/howitzer_155mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_155mm.mdl b/models/howitzer/howitzer_155mm.mdl
index 3242fc9bd..8a2c3fd47 100644
Binary files a/models/howitzer/howitzer_155mm.mdl and b/models/howitzer/howitzer_155mm.mdl differ
diff --git a/models/howitzer/howitzer_155mm.phy b/models/howitzer/howitzer_155mm.phy
index 883de7010..4519c2a2e 100644
Binary files a/models/howitzer/howitzer_155mm.phy and b/models/howitzer/howitzer_155mm.phy differ
diff --git a/models/howitzer/howitzer_155mm.sw.vtx b/models/howitzer/howitzer_155mm.sw.vtx
index 41cd44d2b..3df875c8d 100644
Binary files a/models/howitzer/howitzer_155mm.sw.vtx and b/models/howitzer/howitzer_155mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_155mm.vvd b/models/howitzer/howitzer_155mm.vvd
index 4fb07c519..659584f10 100644
Binary files a/models/howitzer/howitzer_155mm.vvd and b/models/howitzer/howitzer_155mm.vvd differ
diff --git a/models/howitzer/howitzer_203mm.dx80.vtx b/models/howitzer/howitzer_203mm.dx80.vtx
index fb2c64b41..1ab0015d9 100644
Binary files a/models/howitzer/howitzer_203mm.dx80.vtx and b/models/howitzer/howitzer_203mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_203mm.dx90.vtx b/models/howitzer/howitzer_203mm.dx90.vtx
index fd333d161..5e32d86df 100644
Binary files a/models/howitzer/howitzer_203mm.dx90.vtx and b/models/howitzer/howitzer_203mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_203mm.mdl b/models/howitzer/howitzer_203mm.mdl
index 4c1eaa0cb..3f6961b41 100644
Binary files a/models/howitzer/howitzer_203mm.mdl and b/models/howitzer/howitzer_203mm.mdl differ
diff --git a/models/howitzer/howitzer_203mm.phy b/models/howitzer/howitzer_203mm.phy
index 8095d8642..44066b1cc 100644
Binary files a/models/howitzer/howitzer_203mm.phy and b/models/howitzer/howitzer_203mm.phy differ
diff --git a/models/howitzer/howitzer_203mm.sw.vtx b/models/howitzer/howitzer_203mm.sw.vtx
index 0bdd4533d..b717cb46e 100644
Binary files a/models/howitzer/howitzer_203mm.sw.vtx and b/models/howitzer/howitzer_203mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_203mm.vvd b/models/howitzer/howitzer_203mm.vvd
index b04493d28..2cc17a260 100644
Binary files a/models/howitzer/howitzer_203mm.vvd and b/models/howitzer/howitzer_203mm.vvd differ
diff --git a/models/howitzer/howitzer_240mm.dx80.vtx b/models/howitzer/howitzer_240mm.dx80.vtx
new file mode 100644
index 000000000..805025375
Binary files /dev/null and b/models/howitzer/howitzer_240mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_240mm.dx90.vtx b/models/howitzer/howitzer_240mm.dx90.vtx
new file mode 100644
index 000000000..0ff2be014
Binary files /dev/null and b/models/howitzer/howitzer_240mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_240mm.mdl b/models/howitzer/howitzer_240mm.mdl
new file mode 100644
index 000000000..13fab397b
Binary files /dev/null and b/models/howitzer/howitzer_240mm.mdl differ
diff --git a/models/howitzer/howitzer_240mm.phy b/models/howitzer/howitzer_240mm.phy
new file mode 100644
index 000000000..c66605a13
Binary files /dev/null and b/models/howitzer/howitzer_240mm.phy differ
diff --git a/models/howitzer/howitzer_240mm.sw.vtx b/models/howitzer/howitzer_240mm.sw.vtx
new file mode 100644
index 000000000..4a156a23a
Binary files /dev/null and b/models/howitzer/howitzer_240mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_240mm.vvd b/models/howitzer/howitzer_240mm.vvd
new file mode 100644
index 000000000..a49c374b7
Binary files /dev/null and b/models/howitzer/howitzer_240mm.vvd differ
diff --git a/models/howitzer/howitzer_290mm.dx80.vtx b/models/howitzer/howitzer_290mm.dx80.vtx
new file mode 100644
index 000000000..17b5354e7
Binary files /dev/null and b/models/howitzer/howitzer_290mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_290mm.dx90.vtx b/models/howitzer/howitzer_290mm.dx90.vtx
new file mode 100644
index 000000000..df51e1f4d
Binary files /dev/null and b/models/howitzer/howitzer_290mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_290mm.mdl b/models/howitzer/howitzer_290mm.mdl
new file mode 100644
index 000000000..a95dfddc7
Binary files /dev/null and b/models/howitzer/howitzer_290mm.mdl differ
diff --git a/models/howitzer/howitzer_290mm.phy b/models/howitzer/howitzer_290mm.phy
new file mode 100644
index 000000000..3d59de89c
Binary files /dev/null and b/models/howitzer/howitzer_290mm.phy differ
diff --git a/models/howitzer/howitzer_290mm.sw.vtx b/models/howitzer/howitzer_290mm.sw.vtx
new file mode 100644
index 000000000..f461ad098
Binary files /dev/null and b/models/howitzer/howitzer_290mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_290mm.vvd b/models/howitzer/howitzer_290mm.vvd
new file mode 100644
index 000000000..150456439
Binary files /dev/null and b/models/howitzer/howitzer_290mm.vvd differ
diff --git a/models/howitzer/howitzer_406mm.dx80.vtx b/models/howitzer/howitzer_406mm.dx80.vtx
new file mode 100644
index 000000000..82dc2a9f6
Binary files /dev/null and b/models/howitzer/howitzer_406mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_406mm.dx90.vtx b/models/howitzer/howitzer_406mm.dx90.vtx
new file mode 100644
index 000000000..2fa5508fc
Binary files /dev/null and b/models/howitzer/howitzer_406mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_406mm.mdl b/models/howitzer/howitzer_406mm.mdl
new file mode 100644
index 000000000..cd4bd1b51
Binary files /dev/null and b/models/howitzer/howitzer_406mm.mdl differ
diff --git a/models/howitzer/howitzer_406mm.phy b/models/howitzer/howitzer_406mm.phy
new file mode 100644
index 000000000..353e96a27
Binary files /dev/null and b/models/howitzer/howitzer_406mm.phy differ
diff --git a/models/howitzer/howitzer_406mm.sw.vtx b/models/howitzer/howitzer_406mm.sw.vtx
new file mode 100644
index 000000000..52e9363ab
Binary files /dev/null and b/models/howitzer/howitzer_406mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_406mm.vvd b/models/howitzer/howitzer_406mm.vvd
new file mode 100644
index 000000000..f4424d59c
Binary files /dev/null and b/models/howitzer/howitzer_406mm.vvd differ
diff --git a/models/howitzer/howitzer_75mm.dx80.vtx b/models/howitzer/howitzer_75mm.dx80.vtx
index cff0d855e..ddb87c166 100644
Binary files a/models/howitzer/howitzer_75mm.dx80.vtx and b/models/howitzer/howitzer_75mm.dx80.vtx differ
diff --git a/models/howitzer/howitzer_75mm.dx90.vtx b/models/howitzer/howitzer_75mm.dx90.vtx
index fdab61e3f..4638f6ae4 100644
Binary files a/models/howitzer/howitzer_75mm.dx90.vtx and b/models/howitzer/howitzer_75mm.dx90.vtx differ
diff --git a/models/howitzer/howitzer_75mm.mdl b/models/howitzer/howitzer_75mm.mdl
index 819735db2..6c00eb6dc 100644
Binary files a/models/howitzer/howitzer_75mm.mdl and b/models/howitzer/howitzer_75mm.mdl differ
diff --git a/models/howitzer/howitzer_75mm.phy b/models/howitzer/howitzer_75mm.phy
index 045a3d049..af10f1743 100644
Binary files a/models/howitzer/howitzer_75mm.phy and b/models/howitzer/howitzer_75mm.phy differ
diff --git a/models/howitzer/howitzer_75mm.sw.vtx b/models/howitzer/howitzer_75mm.sw.vtx
index 3ebb1cccd..747e73d6c 100644
Binary files a/models/howitzer/howitzer_75mm.sw.vtx and b/models/howitzer/howitzer_75mm.sw.vtx differ
diff --git a/models/howitzer/howitzer_75mm.vvd b/models/howitzer/howitzer_75mm.vvd
index 8e3d8b217..5e396c9f4 100644
Binary files a/models/howitzer/howitzer_75mm.vvd and b/models/howitzer/howitzer_75mm.vvd differ
diff --git a/models/jojobull/wheel_001.dx80.vtx b/models/jojobull/wheel_001.dx80.vtx
new file mode 100644
index 000000000..c2d67b7f0
Binary files /dev/null and b/models/jojobull/wheel_001.dx80.vtx differ
diff --git a/models/jojobull/wheel_001.dx90.vtx b/models/jojobull/wheel_001.dx90.vtx
new file mode 100644
index 000000000..fe20a00ef
Binary files /dev/null and b/models/jojobull/wheel_001.dx90.vtx differ
diff --git a/models/jojobull/wheel_001.mdl b/models/jojobull/wheel_001.mdl
new file mode 100644
index 000000000..97a45b376
Binary files /dev/null and b/models/jojobull/wheel_001.mdl differ
diff --git a/models/jojobull/wheel_001.phy b/models/jojobull/wheel_001.phy
new file mode 100644
index 000000000..05cf9cc10
Binary files /dev/null and b/models/jojobull/wheel_001.phy differ
diff --git a/models/jojobull/wheel_001.sw.vtx b/models/jojobull/wheel_001.sw.vtx
new file mode 100644
index 000000000..32c9267c5
Binary files /dev/null and b/models/jojobull/wheel_001.sw.vtx differ
diff --git a/models/jojobull/wheel_001.vvd b/models/jojobull/wheel_001.vvd
new file mode 100644
index 000000000..b8e9e730e
Binary files /dev/null and b/models/jojobull/wheel_001.vvd differ
diff --git a/models/jojobull/wheel_001.xbox.vtx b/models/jojobull/wheel_001.xbox.vtx
new file mode 100644
index 000000000..a167e47c2
Binary files /dev/null and b/models/jojobull/wheel_001.xbox.vtx differ
diff --git a/models/jojobull/wheel_002.dx80.vtx b/models/jojobull/wheel_002.dx80.vtx
new file mode 100644
index 000000000..03683ede7
Binary files /dev/null and b/models/jojobull/wheel_002.dx80.vtx differ
diff --git a/models/jojobull/wheel_002.dx90.vtx b/models/jojobull/wheel_002.dx90.vtx
new file mode 100644
index 000000000..0381e7a2b
Binary files /dev/null and b/models/jojobull/wheel_002.dx90.vtx differ
diff --git a/models/jojobull/wheel_002.mdl b/models/jojobull/wheel_002.mdl
new file mode 100644
index 000000000..7f7a76c61
Binary files /dev/null and b/models/jojobull/wheel_002.mdl differ
diff --git a/models/jojobull/wheel_002.phy b/models/jojobull/wheel_002.phy
new file mode 100644
index 000000000..0e2dc638a
Binary files /dev/null and b/models/jojobull/wheel_002.phy differ
diff --git a/models/jojobull/wheel_002.sw.vtx b/models/jojobull/wheel_002.sw.vtx
new file mode 100644
index 000000000..ae9dd82de
Binary files /dev/null and b/models/jojobull/wheel_002.sw.vtx differ
diff --git a/models/jojobull/wheel_002.vvd b/models/jojobull/wheel_002.vvd
new file mode 100644
index 000000000..e127309d2
Binary files /dev/null and b/models/jojobull/wheel_002.vvd differ
diff --git a/models/jojobull/wheel_002.xbox.vtx b/models/jojobull/wheel_002.xbox.vtx
new file mode 100644
index 000000000..929eb329d
Binary files /dev/null and b/models/jojobull/wheel_002.xbox.vtx differ
diff --git a/models/jojobull/wheel_003.dx80.vtx b/models/jojobull/wheel_003.dx80.vtx
new file mode 100644
index 000000000..c4766bf00
Binary files /dev/null and b/models/jojobull/wheel_003.dx80.vtx differ
diff --git a/models/jojobull/wheel_003.dx90.vtx b/models/jojobull/wheel_003.dx90.vtx
new file mode 100644
index 000000000..7af757a31
Binary files /dev/null and b/models/jojobull/wheel_003.dx90.vtx differ
diff --git a/models/jojobull/wheel_003.mdl b/models/jojobull/wheel_003.mdl
new file mode 100644
index 000000000..aaf82f14d
Binary files /dev/null and b/models/jojobull/wheel_003.mdl differ
diff --git a/models/jojobull/wheel_003.phy b/models/jojobull/wheel_003.phy
new file mode 100644
index 000000000..b7273423c
Binary files /dev/null and b/models/jojobull/wheel_003.phy differ
diff --git a/models/jojobull/wheel_003.sw.vtx b/models/jojobull/wheel_003.sw.vtx
new file mode 100644
index 000000000..85b283ec3
Binary files /dev/null and b/models/jojobull/wheel_003.sw.vtx differ
diff --git a/models/jojobull/wheel_003.vvd b/models/jojobull/wheel_003.vvd
new file mode 100644
index 000000000..3b639ac2f
Binary files /dev/null and b/models/jojobull/wheel_003.vvd differ
diff --git a/models/jojobull/wheel_003.xbox.vtx b/models/jojobull/wheel_003.xbox.vtx
new file mode 100644
index 000000000..4b8827401
Binary files /dev/null and b/models/jojobull/wheel_003.xbox.vtx differ
diff --git a/models/jojobull/wheel_004.dx80.vtx b/models/jojobull/wheel_004.dx80.vtx
new file mode 100644
index 000000000..55c1671d0
Binary files /dev/null and b/models/jojobull/wheel_004.dx80.vtx differ
diff --git a/models/jojobull/wheel_004.dx90.vtx b/models/jojobull/wheel_004.dx90.vtx
new file mode 100644
index 000000000..24e99b256
Binary files /dev/null and b/models/jojobull/wheel_004.dx90.vtx differ
diff --git a/models/jojobull/wheel_004.mdl b/models/jojobull/wheel_004.mdl
new file mode 100644
index 000000000..6e51c27ed
Binary files /dev/null and b/models/jojobull/wheel_004.mdl differ
diff --git a/models/jojobull/wheel_004.phy b/models/jojobull/wheel_004.phy
new file mode 100644
index 000000000..5bd535ea9
Binary files /dev/null and b/models/jojobull/wheel_004.phy differ
diff --git a/models/jojobull/wheel_004.sw.vtx b/models/jojobull/wheel_004.sw.vtx
new file mode 100644
index 000000000..07ecc9248
Binary files /dev/null and b/models/jojobull/wheel_004.sw.vtx differ
diff --git a/models/jojobull/wheel_004.vvd b/models/jojobull/wheel_004.vvd
new file mode 100644
index 000000000..74953385c
Binary files /dev/null and b/models/jojobull/wheel_004.vvd differ
diff --git a/models/jojobull/wheel_004.xbox.vtx b/models/jojobull/wheel_004.xbox.vtx
new file mode 100644
index 000000000..9f81ffb1a
Binary files /dev/null and b/models/jojobull/wheel_004.xbox.vtx differ
diff --git a/models/jojobull/wheel_005.dx80.vtx b/models/jojobull/wheel_005.dx80.vtx
new file mode 100644
index 000000000..511567032
Binary files /dev/null and b/models/jojobull/wheel_005.dx80.vtx differ
diff --git a/models/jojobull/wheel_005.dx90.vtx b/models/jojobull/wheel_005.dx90.vtx
new file mode 100644
index 000000000..fef95f67c
Binary files /dev/null and b/models/jojobull/wheel_005.dx90.vtx differ
diff --git a/models/jojobull/wheel_005.mdl b/models/jojobull/wheel_005.mdl
new file mode 100644
index 000000000..f0998b400
Binary files /dev/null and b/models/jojobull/wheel_005.mdl differ
diff --git a/models/jojobull/wheel_005.phy b/models/jojobull/wheel_005.phy
new file mode 100644
index 000000000..4895b741b
Binary files /dev/null and b/models/jojobull/wheel_005.phy differ
diff --git a/models/jojobull/wheel_005.sw.vtx b/models/jojobull/wheel_005.sw.vtx
new file mode 100644
index 000000000..603638fba
Binary files /dev/null and b/models/jojobull/wheel_005.sw.vtx differ
diff --git a/models/jojobull/wheel_005.vvd b/models/jojobull/wheel_005.vvd
new file mode 100644
index 000000000..d74f1fa19
Binary files /dev/null and b/models/jojobull/wheel_005.vvd differ
diff --git a/models/jojobull/wheel_005.xbox.vtx b/models/jojobull/wheel_005.xbox.vtx
new file mode 100644
index 000000000..46b0cdfed
Binary files /dev/null and b/models/jojobull/wheel_005.xbox.vtx differ
diff --git a/models/jojobull/wheel_006.dx80.vtx b/models/jojobull/wheel_006.dx80.vtx
new file mode 100644
index 000000000..b9dda603f
Binary files /dev/null and b/models/jojobull/wheel_006.dx80.vtx differ
diff --git a/models/jojobull/wheel_006.dx90.vtx b/models/jojobull/wheel_006.dx90.vtx
new file mode 100644
index 000000000..f93360ed3
Binary files /dev/null and b/models/jojobull/wheel_006.dx90.vtx differ
diff --git a/models/jojobull/wheel_006.mdl b/models/jojobull/wheel_006.mdl
new file mode 100644
index 000000000..6d6590402
Binary files /dev/null and b/models/jojobull/wheel_006.mdl differ
diff --git a/models/jojobull/wheel_006.phy b/models/jojobull/wheel_006.phy
new file mode 100644
index 000000000..3d12cb0da
Binary files /dev/null and b/models/jojobull/wheel_006.phy differ
diff --git a/models/jojobull/wheel_006.sw.vtx b/models/jojobull/wheel_006.sw.vtx
new file mode 100644
index 000000000..55740feb8
Binary files /dev/null and b/models/jojobull/wheel_006.sw.vtx differ
diff --git a/models/jojobull/wheel_006.vvd b/models/jojobull/wheel_006.vvd
new file mode 100644
index 000000000..b03d28e45
Binary files /dev/null and b/models/jojobull/wheel_006.vvd differ
diff --git a/models/jojobull/wheel_006.xbox.vtx b/models/jojobull/wheel_006.xbox.vtx
new file mode 100644
index 000000000..e1d9b3a51
Binary files /dev/null and b/models/jojobull/wheel_006.xbox.vtx differ
diff --git a/models/jojobull/wheel_007.dx80.vtx b/models/jojobull/wheel_007.dx80.vtx
new file mode 100644
index 000000000..abdff5644
Binary files /dev/null and b/models/jojobull/wheel_007.dx80.vtx differ
diff --git a/models/jojobull/wheel_007.dx90.vtx b/models/jojobull/wheel_007.dx90.vtx
new file mode 100644
index 000000000..f8041da75
Binary files /dev/null and b/models/jojobull/wheel_007.dx90.vtx differ
diff --git a/models/jojobull/wheel_007.mdl b/models/jojobull/wheel_007.mdl
new file mode 100644
index 000000000..a5943cd8e
Binary files /dev/null and b/models/jojobull/wheel_007.mdl differ
diff --git a/models/jojobull/wheel_007.phy b/models/jojobull/wheel_007.phy
new file mode 100644
index 000000000..7cad9fef7
Binary files /dev/null and b/models/jojobull/wheel_007.phy differ
diff --git a/models/jojobull/wheel_007.sw.vtx b/models/jojobull/wheel_007.sw.vtx
new file mode 100644
index 000000000..b87a913d5
Binary files /dev/null and b/models/jojobull/wheel_007.sw.vtx differ
diff --git a/models/jojobull/wheel_007.vvd b/models/jojobull/wheel_007.vvd
new file mode 100644
index 000000000..86ea3da95
Binary files /dev/null and b/models/jojobull/wheel_007.vvd differ
diff --git a/models/jojobull/wheel_007.xbox.vtx b/models/jojobull/wheel_007.xbox.vtx
new file mode 100644
index 000000000..13a554b22
Binary files /dev/null and b/models/jojobull/wheel_007.xbox.vtx differ
diff --git a/models/jojobull/wheel_008.dx80.vtx b/models/jojobull/wheel_008.dx80.vtx
new file mode 100644
index 000000000..72ca31d54
Binary files /dev/null and b/models/jojobull/wheel_008.dx80.vtx differ
diff --git a/models/jojobull/wheel_008.dx90.vtx b/models/jojobull/wheel_008.dx90.vtx
new file mode 100644
index 000000000..a8ec2076a
Binary files /dev/null and b/models/jojobull/wheel_008.dx90.vtx differ
diff --git a/models/jojobull/wheel_008.mdl b/models/jojobull/wheel_008.mdl
new file mode 100644
index 000000000..765fff1a4
Binary files /dev/null and b/models/jojobull/wheel_008.mdl differ
diff --git a/models/jojobull/wheel_008.phy b/models/jojobull/wheel_008.phy
new file mode 100644
index 000000000..f357c5a7c
Binary files /dev/null and b/models/jojobull/wheel_008.phy differ
diff --git a/models/jojobull/wheel_008.sw.vtx b/models/jojobull/wheel_008.sw.vtx
new file mode 100644
index 000000000..296bfbaed
Binary files /dev/null and b/models/jojobull/wheel_008.sw.vtx differ
diff --git a/models/jojobull/wheel_008.vvd b/models/jojobull/wheel_008.vvd
new file mode 100644
index 000000000..bdef8b5b7
Binary files /dev/null and b/models/jojobull/wheel_008.vvd differ
diff --git a/models/jojobull/wheel_008.xbox.vtx b/models/jojobull/wheel_008.xbox.vtx
new file mode 100644
index 000000000..d8eaea44f
Binary files /dev/null and b/models/jojobull/wheel_008.xbox.vtx differ
diff --git a/models/jojobull/wheel_009.dx80.vtx b/models/jojobull/wheel_009.dx80.vtx
new file mode 100644
index 000000000..35f3cdfa5
Binary files /dev/null and b/models/jojobull/wheel_009.dx80.vtx differ
diff --git a/models/jojobull/wheel_009.dx90.vtx b/models/jojobull/wheel_009.dx90.vtx
new file mode 100644
index 000000000..1b87d5833
Binary files /dev/null and b/models/jojobull/wheel_009.dx90.vtx differ
diff --git a/models/jojobull/wheel_009.mdl b/models/jojobull/wheel_009.mdl
new file mode 100644
index 000000000..b6c69cd8a
Binary files /dev/null and b/models/jojobull/wheel_009.mdl differ
diff --git a/models/jojobull/wheel_009.phy b/models/jojobull/wheel_009.phy
new file mode 100644
index 000000000..1f61e7047
Binary files /dev/null and b/models/jojobull/wheel_009.phy differ
diff --git a/models/jojobull/wheel_009.sw.vtx b/models/jojobull/wheel_009.sw.vtx
new file mode 100644
index 000000000..d69520245
Binary files /dev/null and b/models/jojobull/wheel_009.sw.vtx differ
diff --git a/models/jojobull/wheel_009.vvd b/models/jojobull/wheel_009.vvd
new file mode 100644
index 000000000..7bc95bbed
Binary files /dev/null and b/models/jojobull/wheel_009.vvd differ
diff --git a/models/jojobull/wheel_009.xbox.vtx b/models/jojobull/wheel_009.xbox.vtx
new file mode 100644
index 000000000..51ca186bd
Binary files /dev/null and b/models/jojobull/wheel_009.xbox.vtx differ
diff --git a/models/jojobull/wheel_010.dx80.vtx b/models/jojobull/wheel_010.dx80.vtx
new file mode 100644
index 000000000..37a4d5841
Binary files /dev/null and b/models/jojobull/wheel_010.dx80.vtx differ
diff --git a/models/jojobull/wheel_010.dx90.vtx b/models/jojobull/wheel_010.dx90.vtx
new file mode 100644
index 000000000..03ed3ccf8
Binary files /dev/null and b/models/jojobull/wheel_010.dx90.vtx differ
diff --git a/models/jojobull/wheel_010.mdl b/models/jojobull/wheel_010.mdl
new file mode 100644
index 000000000..f63098924
Binary files /dev/null and b/models/jojobull/wheel_010.mdl differ
diff --git a/models/jojobull/wheel_010.phy b/models/jojobull/wheel_010.phy
new file mode 100644
index 000000000..4c5429336
Binary files /dev/null and b/models/jojobull/wheel_010.phy differ
diff --git a/models/jojobull/wheel_010.sw.vtx b/models/jojobull/wheel_010.sw.vtx
new file mode 100644
index 000000000..6622d3b2a
Binary files /dev/null and b/models/jojobull/wheel_010.sw.vtx differ
diff --git a/models/jojobull/wheel_010.vvd b/models/jojobull/wheel_010.vvd
new file mode 100644
index 000000000..c246d04d2
Binary files /dev/null and b/models/jojobull/wheel_010.vvd differ
diff --git a/models/jojobull/wheel_010.xbox.vtx b/models/jojobull/wheel_010.xbox.vtx
new file mode 100644
index 000000000..d34ee2724
Binary files /dev/null and b/models/jojobull/wheel_010.xbox.vtx differ
diff --git a/models/jojobull/wheel_011.dx80.vtx b/models/jojobull/wheel_011.dx80.vtx
new file mode 100644
index 000000000..620a684cb
Binary files /dev/null and b/models/jojobull/wheel_011.dx80.vtx differ
diff --git a/models/jojobull/wheel_011.dx90.vtx b/models/jojobull/wheel_011.dx90.vtx
new file mode 100644
index 000000000..d48b16c63
Binary files /dev/null and b/models/jojobull/wheel_011.dx90.vtx differ
diff --git a/models/jojobull/wheel_011.mdl b/models/jojobull/wheel_011.mdl
new file mode 100644
index 000000000..71b54dd6e
Binary files /dev/null and b/models/jojobull/wheel_011.mdl differ
diff --git a/models/jojobull/wheel_011.phy b/models/jojobull/wheel_011.phy
new file mode 100644
index 000000000..3537b430f
Binary files /dev/null and b/models/jojobull/wheel_011.phy differ
diff --git a/models/jojobull/wheel_011.sw.vtx b/models/jojobull/wheel_011.sw.vtx
new file mode 100644
index 000000000..87bd7a672
Binary files /dev/null and b/models/jojobull/wheel_011.sw.vtx differ
diff --git a/models/jojobull/wheel_011.vvd b/models/jojobull/wheel_011.vvd
new file mode 100644
index 000000000..c517603f6
Binary files /dev/null and b/models/jojobull/wheel_011.vvd differ
diff --git a/models/jojobull/wheel_011.xbox.vtx b/models/jojobull/wheel_011.xbox.vtx
new file mode 100644
index 000000000..6dde20645
Binary files /dev/null and b/models/jojobull/wheel_011.xbox.vtx differ
diff --git a/models/jojobull/wheel_012.dx80.vtx b/models/jojobull/wheel_012.dx80.vtx
new file mode 100644
index 000000000..e4931f5e1
Binary files /dev/null and b/models/jojobull/wheel_012.dx80.vtx differ
diff --git a/models/jojobull/wheel_012.dx90.vtx b/models/jojobull/wheel_012.dx90.vtx
new file mode 100644
index 000000000..b61a0f4c8
Binary files /dev/null and b/models/jojobull/wheel_012.dx90.vtx differ
diff --git a/models/jojobull/wheel_012.mdl b/models/jojobull/wheel_012.mdl
new file mode 100644
index 000000000..fd97091fa
Binary files /dev/null and b/models/jojobull/wheel_012.mdl differ
diff --git a/models/jojobull/wheel_012.phy b/models/jojobull/wheel_012.phy
new file mode 100644
index 000000000..f58688f14
Binary files /dev/null and b/models/jojobull/wheel_012.phy differ
diff --git a/models/jojobull/wheel_012.sw.vtx b/models/jojobull/wheel_012.sw.vtx
new file mode 100644
index 000000000..760c70733
Binary files /dev/null and b/models/jojobull/wheel_012.sw.vtx differ
diff --git a/models/jojobull/wheel_012.vvd b/models/jojobull/wheel_012.vvd
new file mode 100644
index 000000000..f54e651c1
Binary files /dev/null and b/models/jojobull/wheel_012.vvd differ
diff --git a/models/jojobull/wheel_012.xbox.vtx b/models/jojobull/wheel_012.xbox.vtx
new file mode 100644
index 000000000..79cf1cd20
Binary files /dev/null and b/models/jojobull/wheel_012.xbox.vtx differ
diff --git a/models/launcher/40mmsl.dx80.vtx b/models/launcher/40mmsl.dx80.vtx
new file mode 100644
index 000000000..0483dea65
Binary files /dev/null and b/models/launcher/40mmsl.dx80.vtx differ
diff --git a/models/launcher/40mmsl.dx90.vtx b/models/launcher/40mmsl.dx90.vtx
new file mode 100644
index 000000000..b4420bf74
Binary files /dev/null and b/models/launcher/40mmsl.dx90.vtx differ
diff --git a/models/launcher/40mmsl.mdl b/models/launcher/40mmsl.mdl
new file mode 100644
index 000000000..0ec7705d4
Binary files /dev/null and b/models/launcher/40mmsl.mdl differ
diff --git a/models/launcher/40mmsl.phy b/models/launcher/40mmsl.phy
new file mode 100644
index 000000000..7b799cd69
Binary files /dev/null and b/models/launcher/40mmsl.phy differ
diff --git a/models/launcher/40mmsl.sw.vtx b/models/launcher/40mmsl.sw.vtx
new file mode 100644
index 000000000..db62d17eb
Binary files /dev/null and b/models/launcher/40mmsl.sw.vtx differ
diff --git a/models/launcher/40mmsl.vvd b/models/launcher/40mmsl.vvd
new file mode 100644
index 000000000..23cdf1ada
Binary files /dev/null and b/models/launcher/40mmsl.vvd differ
diff --git a/models/machinegun/machinegun_127mm.dx80.vtx b/models/machinegun/machinegun_127mm.dx80.vtx
index c2f5fca8f..e74d28c27 100644
Binary files a/models/machinegun/machinegun_127mm.dx80.vtx and b/models/machinegun/machinegun_127mm.dx80.vtx differ
diff --git a/models/machinegun/machinegun_127mm.dx90.vtx b/models/machinegun/machinegun_127mm.dx90.vtx
index d370e5e57..10494143f 100644
Binary files a/models/machinegun/machinegun_127mm.dx90.vtx and b/models/machinegun/machinegun_127mm.dx90.vtx differ
diff --git a/models/machinegun/machinegun_127mm.mdl b/models/machinegun/machinegun_127mm.mdl
index 2ce443770..005ea8549 100644
Binary files a/models/machinegun/machinegun_127mm.mdl and b/models/machinegun/machinegun_127mm.mdl differ
diff --git a/models/machinegun/machinegun_127mm.phy b/models/machinegun/machinegun_127mm.phy
index 01e3cd38d..2eceb1e8c 100644
Binary files a/models/machinegun/machinegun_127mm.phy and b/models/machinegun/machinegun_127mm.phy differ
diff --git a/models/machinegun/machinegun_127mm.sw.vtx b/models/machinegun/machinegun_127mm.sw.vtx
index c546654c6..0fcacf8fb 100644
Binary files a/models/machinegun/machinegun_127mm.sw.vtx and b/models/machinegun/machinegun_127mm.sw.vtx differ
diff --git a/models/machinegun/machinegun_127mm.vvd b/models/machinegun/machinegun_127mm.vvd
index c3fe1345e..841a6db4e 100644
Binary files a/models/machinegun/machinegun_127mm.vvd and b/models/machinegun/machinegun_127mm.vvd differ
diff --git a/models/machinegun/machinegun_145mm.dx80.vtx b/models/machinegun/machinegun_145mm.dx80.vtx
index 88b1614ac..556f908d2 100644
Binary files a/models/machinegun/machinegun_145mm.dx80.vtx and b/models/machinegun/machinegun_145mm.dx80.vtx differ
diff --git a/models/machinegun/machinegun_145mm.dx90.vtx b/models/machinegun/machinegun_145mm.dx90.vtx
index 1000b4c90..edbd2a878 100644
Binary files a/models/machinegun/machinegun_145mm.dx90.vtx and b/models/machinegun/machinegun_145mm.dx90.vtx differ
diff --git a/models/machinegun/machinegun_145mm.mdl b/models/machinegun/machinegun_145mm.mdl
index 683fd6935..582a571a2 100644
Binary files a/models/machinegun/machinegun_145mm.mdl and b/models/machinegun/machinegun_145mm.mdl differ
diff --git a/models/machinegun/machinegun_145mm.phy b/models/machinegun/machinegun_145mm.phy
index d92bbfc79..b4b4c3656 100644
Binary files a/models/machinegun/machinegun_145mm.phy and b/models/machinegun/machinegun_145mm.phy differ
diff --git a/models/machinegun/machinegun_145mm.sw.vtx b/models/machinegun/machinegun_145mm.sw.vtx
index d59928c62..2f0fd4763 100644
Binary files a/models/machinegun/machinegun_145mm.sw.vtx and b/models/machinegun/machinegun_145mm.sw.vtx differ
diff --git a/models/machinegun/machinegun_145mm.vvd b/models/machinegun/machinegun_145mm.vvd
index 10b758756..e1270815a 100644
Binary files a/models/machinegun/machinegun_145mm.vvd and b/models/machinegun/machinegun_145mm.vvd differ
diff --git a/models/machinegun/machinegun_20mm.dx80.vtx b/models/machinegun/machinegun_20mm.dx80.vtx
index bfcfd98d9..69c86a462 100644
Binary files a/models/machinegun/machinegun_20mm.dx80.vtx and b/models/machinegun/machinegun_20mm.dx80.vtx differ
diff --git a/models/machinegun/machinegun_20mm.dx90.vtx b/models/machinegun/machinegun_20mm.dx90.vtx
index 4e49f1f9e..4771d0a7f 100644
Binary files a/models/machinegun/machinegun_20mm.dx90.vtx and b/models/machinegun/machinegun_20mm.dx90.vtx differ
diff --git a/models/machinegun/machinegun_20mm.mdl b/models/machinegun/machinegun_20mm.mdl
index 0f8d5ee7b..b2b3cbb04 100644
Binary files a/models/machinegun/machinegun_20mm.mdl and b/models/machinegun/machinegun_20mm.mdl differ
diff --git a/models/machinegun/machinegun_20mm.phy b/models/machinegun/machinegun_20mm.phy
index 70cee0d93..45e75abde 100644
Binary files a/models/machinegun/machinegun_20mm.phy and b/models/machinegun/machinegun_20mm.phy differ
diff --git a/models/machinegun/machinegun_20mm.sw.vtx b/models/machinegun/machinegun_20mm.sw.vtx
index 5f92ca809..07495b5f3 100644
Binary files a/models/machinegun/machinegun_20mm.sw.vtx and b/models/machinegun/machinegun_20mm.sw.vtx differ
diff --git a/models/machinegun/machinegun_20mm.vvd b/models/machinegun/machinegun_20mm.vvd
index edf97d9e4..427f95f5f 100644
Binary files a/models/machinegun/machinegun_20mm.vvd and b/models/machinegun/machinegun_20mm.vvd differ
diff --git a/models/machinegun/machinegun_20mm_compact.dx80.vtx b/models/machinegun/machinegun_20mm_compact.dx80.vtx
index e00ef15f3..271c7a466 100644
Binary files a/models/machinegun/machinegun_20mm_compact.dx80.vtx and b/models/machinegun/machinegun_20mm_compact.dx80.vtx differ
diff --git a/models/machinegun/machinegun_20mm_compact.dx90.vtx b/models/machinegun/machinegun_20mm_compact.dx90.vtx
index 8c134d84b..170ce6765 100644
Binary files a/models/machinegun/machinegun_20mm_compact.dx90.vtx and b/models/machinegun/machinegun_20mm_compact.dx90.vtx differ
diff --git a/models/machinegun/machinegun_20mm_compact.mdl b/models/machinegun/machinegun_20mm_compact.mdl
index 60824c646..c4a3bf130 100644
Binary files a/models/machinegun/machinegun_20mm_compact.mdl and b/models/machinegun/machinegun_20mm_compact.mdl differ
diff --git a/models/machinegun/machinegun_20mm_compact.phy b/models/machinegun/machinegun_20mm_compact.phy
index a3fac5fda..492ab23c5 100644
Binary files a/models/machinegun/machinegun_20mm_compact.phy and b/models/machinegun/machinegun_20mm_compact.phy differ
diff --git a/models/machinegun/machinegun_20mm_compact.sw.vtx b/models/machinegun/machinegun_20mm_compact.sw.vtx
index ae6796460..11ba564c3 100644
Binary files a/models/machinegun/machinegun_20mm_compact.sw.vtx and b/models/machinegun/machinegun_20mm_compact.sw.vtx differ
diff --git a/models/machinegun/machinegun_20mm_compact.vvd b/models/machinegun/machinegun_20mm_compact.vvd
index cb9f32169..ecf381a82 100644
Binary files a/models/machinegun/machinegun_20mm_compact.vvd and b/models/machinegun/machinegun_20mm_compact.vvd differ
diff --git a/models/machinegun/machinegun_30mm.dx80.vtx b/models/machinegun/machinegun_30mm.dx80.vtx
index e1e4a7648..c710f1eed 100644
Binary files a/models/machinegun/machinegun_30mm.dx80.vtx and b/models/machinegun/machinegun_30mm.dx80.vtx differ
diff --git a/models/machinegun/machinegun_30mm.dx90.vtx b/models/machinegun/machinegun_30mm.dx90.vtx
index 8179def88..3498be21b 100644
Binary files a/models/machinegun/machinegun_30mm.dx90.vtx and b/models/machinegun/machinegun_30mm.dx90.vtx differ
diff --git a/models/machinegun/machinegun_30mm.mdl b/models/machinegun/machinegun_30mm.mdl
index e70cfcec5..2d74b7064 100644
Binary files a/models/machinegun/machinegun_30mm.mdl and b/models/machinegun/machinegun_30mm.mdl differ
diff --git a/models/machinegun/machinegun_30mm.phy b/models/machinegun/machinegun_30mm.phy
index cfad1271f..674445d55 100644
Binary files a/models/machinegun/machinegun_30mm.phy and b/models/machinegun/machinegun_30mm.phy differ
diff --git a/models/machinegun/machinegun_30mm.sw.vtx b/models/machinegun/machinegun_30mm.sw.vtx
index cfff5dad1..232d89af8 100644
Binary files a/models/machinegun/machinegun_30mm.sw.vtx and b/models/machinegun/machinegun_30mm.sw.vtx differ
diff --git a/models/machinegun/machinegun_30mm.vvd b/models/machinegun/machinegun_30mm.vvd
index eec6e7e5c..de14e0d0b 100644
Binary files a/models/machinegun/machinegun_30mm.vvd and b/models/machinegun/machinegun_30mm.vvd differ
diff --git a/models/machinegun/machinegun_30mm_compact.dx80.vtx b/models/machinegun/machinegun_30mm_compact.dx80.vtx
index fc26fe9db..7efd31d6f 100644
Binary files a/models/machinegun/machinegun_30mm_compact.dx80.vtx and b/models/machinegun/machinegun_30mm_compact.dx80.vtx differ
diff --git a/models/machinegun/machinegun_30mm_compact.dx90.vtx b/models/machinegun/machinegun_30mm_compact.dx90.vtx
index 53da1e585..84aa46a3d 100644
Binary files a/models/machinegun/machinegun_30mm_compact.dx90.vtx and b/models/machinegun/machinegun_30mm_compact.dx90.vtx differ
diff --git a/models/machinegun/machinegun_30mm_compact.mdl b/models/machinegun/machinegun_30mm_compact.mdl
index 65bdca0d9..066a468d8 100644
Binary files a/models/machinegun/machinegun_30mm_compact.mdl and b/models/machinegun/machinegun_30mm_compact.mdl differ
diff --git a/models/machinegun/machinegun_30mm_compact.phy b/models/machinegun/machinegun_30mm_compact.phy
index 7837cd38b..36013dddd 100644
Binary files a/models/machinegun/machinegun_30mm_compact.phy and b/models/machinegun/machinegun_30mm_compact.phy differ
diff --git a/models/machinegun/machinegun_30mm_compact.sw.vtx b/models/machinegun/machinegun_30mm_compact.sw.vtx
index 18feeece0..b1b71ccce 100644
Binary files a/models/machinegun/machinegun_30mm_compact.sw.vtx and b/models/machinegun/machinegun_30mm_compact.sw.vtx differ
diff --git a/models/machinegun/machinegun_30mm_compact.vvd b/models/machinegun/machinegun_30mm_compact.vvd
index 124f4e0fb..b1db54bd1 100644
Binary files a/models/machinegun/machinegun_30mm_compact.vvd and b/models/machinegun/machinegun_30mm_compact.vvd differ
diff --git a/models/machinegun/machinegun_40mm_compact.dx80.vtx b/models/machinegun/machinegun_40mm_compact.dx80.vtx
index 29067e855..7f37156aa 100644
Binary files a/models/machinegun/machinegun_40mm_compact.dx80.vtx and b/models/machinegun/machinegun_40mm_compact.dx80.vtx differ
diff --git a/models/machinegun/machinegun_40mm_compact.dx90.vtx b/models/machinegun/machinegun_40mm_compact.dx90.vtx
index 8242830f3..0c82d772d 100644
Binary files a/models/machinegun/machinegun_40mm_compact.dx90.vtx and b/models/machinegun/machinegun_40mm_compact.dx90.vtx differ
diff --git a/models/machinegun/machinegun_40mm_compact.mdl b/models/machinegun/machinegun_40mm_compact.mdl
index 2af269f18..40a91f838 100644
Binary files a/models/machinegun/machinegun_40mm_compact.mdl and b/models/machinegun/machinegun_40mm_compact.mdl differ
diff --git a/models/machinegun/machinegun_40mm_compact.phy b/models/machinegun/machinegun_40mm_compact.phy
index 21a21b9ef..32b641e15 100644
Binary files a/models/machinegun/machinegun_40mm_compact.phy and b/models/machinegun/machinegun_40mm_compact.phy differ
diff --git a/models/machinegun/machinegun_40mm_compact.sw.vtx b/models/machinegun/machinegun_40mm_compact.sw.vtx
index 25e5e8d95..5b0b0ac6a 100644
Binary files a/models/machinegun/machinegun_40mm_compact.sw.vtx and b/models/machinegun/machinegun_40mm_compact.sw.vtx differ
diff --git a/models/machinegun/machinegun_40mm_compact.vvd b/models/machinegun/machinegun_40mm_compact.vvd
index edd83529d..e49fc9ea9 100644
Binary files a/models/machinegun/machinegun_40mm_compact.vvd and b/models/machinegun/machinegun_40mm_compact.vvd differ
diff --git a/models/machinegun/machinegun_762mm.dx80.vtx b/models/machinegun/machinegun_762mm.dx80.vtx
new file mode 100644
index 000000000..b95a6dcab
Binary files /dev/null and b/models/machinegun/machinegun_762mm.dx80.vtx differ
diff --git a/models/machinegun/machinegun_762mm.dx90.vtx b/models/machinegun/machinegun_762mm.dx90.vtx
new file mode 100644
index 000000000..2d27240b3
Binary files /dev/null and b/models/machinegun/machinegun_762mm.dx90.vtx differ
diff --git a/models/machinegun/machinegun_762mm.mdl b/models/machinegun/machinegun_762mm.mdl
new file mode 100644
index 000000000..6758c92af
Binary files /dev/null and b/models/machinegun/machinegun_762mm.mdl differ
diff --git a/models/machinegun/machinegun_762mm.phy b/models/machinegun/machinegun_762mm.phy
new file mode 100644
index 000000000..ecb702f97
Binary files /dev/null and b/models/machinegun/machinegun_762mm.phy differ
diff --git a/models/machinegun/machinegun_762mm.sw.vtx b/models/machinegun/machinegun_762mm.sw.vtx
new file mode 100644
index 000000000..4303791a2
Binary files /dev/null and b/models/machinegun/machinegun_762mm.sw.vtx differ
diff --git a/models/machinegun/machinegun_762mm.vvd b/models/machinegun/machinegun_762mm.vvd
new file mode 100644
index 000000000..a1a6c6fad
Binary files /dev/null and b/models/machinegun/machinegun_762mm.vvd differ
diff --git a/models/missiles/70mmFFAR.dx80.vtx b/models/missiles/70mmffar.dx80.vtx
similarity index 100%
rename from models/missiles/70mmFFAR.dx80.vtx
rename to models/missiles/70mmffar.dx80.vtx
diff --git a/models/missiles/70mmFFAR.dx90.vtx b/models/missiles/70mmffar.dx90.vtx
similarity index 100%
rename from models/missiles/70mmFFAR.dx90.vtx
rename to models/missiles/70mmffar.dx90.vtx
diff --git a/models/missiles/70mmFFAR.phy b/models/missiles/70mmffar.phy
similarity index 100%
rename from models/missiles/70mmFFAR.phy
rename to models/missiles/70mmffar.phy
diff --git a/models/missiles/70mmFFAR.sw.vtx b/models/missiles/70mmffar.sw.vtx
similarity index 100%
rename from models/missiles/70mmFFAR.sw.vtx
rename to models/missiles/70mmffar.sw.vtx
diff --git a/models/missiles/AIM120.dx80.vtx b/models/missiles/aim120.dx80.vtx
similarity index 100%
rename from models/missiles/AIM120.dx80.vtx
rename to models/missiles/aim120.dx80.vtx
diff --git a/models/missiles/AIM120.dx90.vtx b/models/missiles/aim120.dx90.vtx
similarity index 100%
rename from models/missiles/AIM120.dx90.vtx
rename to models/missiles/aim120.dx90.vtx
diff --git a/models/missiles/AIM120.phy b/models/missiles/aim120.phy
similarity index 100%
rename from models/missiles/AIM120.phy
rename to models/missiles/aim120.phy
diff --git a/models/missiles/AIM120.sw.vtx b/models/missiles/aim120.sw.vtx
similarity index 100%
rename from models/missiles/AIM120.sw.vtx
rename to models/missiles/aim120.sw.vtx
diff --git a/models/missiles/ECM.dx80.vtx b/models/missiles/ecm.dx80.vtx
similarity index 100%
rename from models/missiles/ECM.dx80.vtx
rename to models/missiles/ecm.dx80.vtx
diff --git a/models/missiles/ECM.dx90.vtx b/models/missiles/ecm.dx90.vtx
similarity index 100%
rename from models/missiles/ECM.dx90.vtx
rename to models/missiles/ecm.dx90.vtx
diff --git a/models/missiles/ECM.phy b/models/missiles/ecm.phy
similarity index 100%
rename from models/missiles/ECM.phy
rename to models/missiles/ecm.phy
diff --git a/models/missiles/ECM.sw.vtx b/models/missiles/ecm.sw.vtx
similarity index 100%
rename from models/missiles/ECM.sw.vtx
rename to models/missiles/ecm.sw.vtx
diff --git a/models/missiles/FAB250.dx80.vtx b/models/missiles/fab250.dx80.vtx
similarity index 100%
rename from models/missiles/FAB250.dx80.vtx
rename to models/missiles/fab250.dx80.vtx
diff --git a/models/missiles/FAB250.dx90.vtx b/models/missiles/fab250.dx90.vtx
similarity index 100%
rename from models/missiles/FAB250.dx90.vtx
rename to models/missiles/fab250.dx90.vtx
diff --git a/models/missiles/FAB250.phy b/models/missiles/fab250.phy
similarity index 100%
rename from models/missiles/FAB250.phy
rename to models/missiles/fab250.phy
diff --git a/models/missiles/FAB250.sw.vtx b/models/missiles/fab250.sw.vtx
similarity index 100%
rename from models/missiles/FAB250.sw.vtx
rename to models/missiles/fab250.sw.vtx
diff --git a/models/missiles/GBU12.dx80.vtx b/models/missiles/gbu12.dx80.vtx
similarity index 100%
rename from models/missiles/GBU12.dx80.vtx
rename to models/missiles/gbu12.dx80.vtx
diff --git a/models/missiles/GBU12.dx90.vtx b/models/missiles/gbu12.dx90.vtx
similarity index 100%
rename from models/missiles/GBU12.dx90.vtx
rename to models/missiles/gbu12.dx90.vtx
diff --git a/models/missiles/GBU12.phy b/models/missiles/gbu12.phy
similarity index 100%
rename from models/missiles/GBU12.phy
rename to models/missiles/gbu12.phy
diff --git a/models/missiles/GBU12.sw.vtx b/models/missiles/gbu12.sw.vtx
similarity index 100%
rename from models/missiles/GBU12.sw.vtx
rename to models/missiles/gbu12.sw.vtx
diff --git a/models/mortar/mortar_120mm.dx80.vtx b/models/mortar/mortar_120mm.dx80.vtx
index 791cb921e..9cc9a5561 100644
Binary files a/models/mortar/mortar_120mm.dx80.vtx and b/models/mortar/mortar_120mm.dx80.vtx differ
diff --git a/models/mortar/mortar_120mm.dx90.vtx b/models/mortar/mortar_120mm.dx90.vtx
index a4c235d40..913c43fc8 100644
Binary files a/models/mortar/mortar_120mm.dx90.vtx and b/models/mortar/mortar_120mm.dx90.vtx differ
diff --git a/models/mortar/mortar_120mm.mdl b/models/mortar/mortar_120mm.mdl
index d5705a8ef..e6f822eaf 100644
Binary files a/models/mortar/mortar_120mm.mdl and b/models/mortar/mortar_120mm.mdl differ
diff --git a/models/mortar/mortar_120mm.sw.vtx b/models/mortar/mortar_120mm.sw.vtx
index 502be61ea..23f9d19fb 100644
Binary files a/models/mortar/mortar_120mm.sw.vtx and b/models/mortar/mortar_120mm.sw.vtx differ
diff --git a/models/mortar/mortar_120mm.vvd b/models/mortar/mortar_120mm.vvd
index 8f29ccdc5..b4210a8fc 100644
Binary files a/models/mortar/mortar_120mm.vvd and b/models/mortar/mortar_120mm.vvd differ
diff --git a/models/mortar/mortar_150mm.dx80.vtx b/models/mortar/mortar_150mm.dx80.vtx
new file mode 100644
index 000000000..325a0884f
Binary files /dev/null and b/models/mortar/mortar_150mm.dx80.vtx differ
diff --git a/models/mortar/mortar_150mm.dx90.vtx b/models/mortar/mortar_150mm.dx90.vtx
new file mode 100644
index 000000000..9c24174c2
Binary files /dev/null and b/models/mortar/mortar_150mm.dx90.vtx differ
diff --git a/models/mortar/mortar_150mm.mdl b/models/mortar/mortar_150mm.mdl
new file mode 100644
index 000000000..cc823b37c
Binary files /dev/null and b/models/mortar/mortar_150mm.mdl differ
diff --git a/models/mortar/mortar_150mm.phy b/models/mortar/mortar_150mm.phy
new file mode 100644
index 000000000..2b145cb35
Binary files /dev/null and b/models/mortar/mortar_150mm.phy differ
diff --git a/models/mortar/mortar_150mm.sw.vtx b/models/mortar/mortar_150mm.sw.vtx
new file mode 100644
index 000000000..eb5719722
Binary files /dev/null and b/models/mortar/mortar_150mm.sw.vtx differ
diff --git a/models/mortar/mortar_150mm.vvd b/models/mortar/mortar_150mm.vvd
new file mode 100644
index 000000000..de4a030cf
Binary files /dev/null and b/models/mortar/mortar_150mm.vvd differ
diff --git a/models/mortar/mortar_200mm.dx80.vtx b/models/mortar/mortar_200mm.dx80.vtx
index 2ac59fb37..9549ae94c 100644
Binary files a/models/mortar/mortar_200mm.dx80.vtx and b/models/mortar/mortar_200mm.dx80.vtx differ
diff --git a/models/mortar/mortar_200mm.dx90.vtx b/models/mortar/mortar_200mm.dx90.vtx
index 3795fc81d..824205f05 100644
Binary files a/models/mortar/mortar_200mm.dx90.vtx and b/models/mortar/mortar_200mm.dx90.vtx differ
diff --git a/models/mortar/mortar_200mm.mdl b/models/mortar/mortar_200mm.mdl
index cd629ff4a..46a4c7deb 100644
Binary files a/models/mortar/mortar_200mm.mdl and b/models/mortar/mortar_200mm.mdl differ
diff --git a/models/mortar/mortar_200mm.sw.vtx b/models/mortar/mortar_200mm.sw.vtx
index 2d41bbe54..e9744dc4a 100644
Binary files a/models/mortar/mortar_200mm.sw.vtx and b/models/mortar/mortar_200mm.sw.vtx differ
diff --git a/models/mortar/mortar_200mm.vvd b/models/mortar/mortar_200mm.vvd
index d7b2a7f2a..c0260ea0c 100644
Binary files a/models/mortar/mortar_200mm.vvd and b/models/mortar/mortar_200mm.vvd differ
diff --git a/models/mortar/mortar_280mm.dx80.vtx b/models/mortar/mortar_280mm.dx80.vtx
new file mode 100644
index 000000000..e25c72972
Binary files /dev/null and b/models/mortar/mortar_280mm.dx80.vtx differ
diff --git a/models/mortar/mortar_280mm.dx90.vtx b/models/mortar/mortar_280mm.dx90.vtx
new file mode 100644
index 000000000..d5926e527
Binary files /dev/null and b/models/mortar/mortar_280mm.dx90.vtx differ
diff --git a/models/mortar/mortar_280mm.mdl b/models/mortar/mortar_280mm.mdl
new file mode 100644
index 000000000..c1f59c45b
Binary files /dev/null and b/models/mortar/mortar_280mm.mdl differ
diff --git a/models/mortar/mortar_280mm.phy b/models/mortar/mortar_280mm.phy
new file mode 100644
index 000000000..74d1cea84
Binary files /dev/null and b/models/mortar/mortar_280mm.phy differ
diff --git a/models/mortar/mortar_280mm.sw.vtx b/models/mortar/mortar_280mm.sw.vtx
new file mode 100644
index 000000000..e9e16d34a
Binary files /dev/null and b/models/mortar/mortar_280mm.sw.vtx differ
diff --git a/models/mortar/mortar_280mm.vvd b/models/mortar/mortar_280mm.vvd
new file mode 100644
index 000000000..b3b85c5a6
Binary files /dev/null and b/models/mortar/mortar_280mm.vvd differ
diff --git a/models/mortar/mortar_60mm.dx80.vtx b/models/mortar/mortar_60mm.dx80.vtx
new file mode 100644
index 000000000..ac206367c
Binary files /dev/null and b/models/mortar/mortar_60mm.dx80.vtx differ
diff --git a/models/mortar/mortar_60mm.dx90.vtx b/models/mortar/mortar_60mm.dx90.vtx
new file mode 100644
index 000000000..9e7c77881
Binary files /dev/null and b/models/mortar/mortar_60mm.dx90.vtx differ
diff --git a/models/mortar/mortar_60mm.mdl b/models/mortar/mortar_60mm.mdl
new file mode 100644
index 000000000..60f1f4e11
Binary files /dev/null and b/models/mortar/mortar_60mm.mdl differ
diff --git a/models/mortar/mortar_60mm.phy b/models/mortar/mortar_60mm.phy
new file mode 100644
index 000000000..ad9a79f7a
Binary files /dev/null and b/models/mortar/mortar_60mm.phy differ
diff --git a/models/mortar/mortar_60mm.sw.vtx b/models/mortar/mortar_60mm.sw.vtx
new file mode 100644
index 000000000..348c57451
Binary files /dev/null and b/models/mortar/mortar_60mm.sw.vtx differ
diff --git a/models/mortar/mortar_60mm.vvd b/models/mortar/mortar_60mm.vvd
new file mode 100644
index 000000000..f5e56bb81
Binary files /dev/null and b/models/mortar/mortar_60mm.vvd differ
diff --git a/models/mortar/mortar_80mm.dx80.vtx b/models/mortar/mortar_80mm.dx80.vtx
index c2bd52d3a..b37a4322a 100644
Binary files a/models/mortar/mortar_80mm.dx80.vtx and b/models/mortar/mortar_80mm.dx80.vtx differ
diff --git a/models/mortar/mortar_80mm.dx90.vtx b/models/mortar/mortar_80mm.dx90.vtx
index 0f01e5248..a380ea7d3 100644
Binary files a/models/mortar/mortar_80mm.dx90.vtx and b/models/mortar/mortar_80mm.dx90.vtx differ
diff --git a/models/mortar/mortar_80mm.mdl b/models/mortar/mortar_80mm.mdl
index d3b868d50..c4ba7954c 100644
Binary files a/models/mortar/mortar_80mm.mdl and b/models/mortar/mortar_80mm.mdl differ
diff --git a/models/mortar/mortar_80mm.sw.vtx b/models/mortar/mortar_80mm.sw.vtx
index b43b6ed2c..b7de23b8d 100644
Binary files a/models/mortar/mortar_80mm.sw.vtx and b/models/mortar/mortar_80mm.sw.vtx differ
diff --git a/models/mortar/mortar_80mm.vvd b/models/mortar/mortar_80mm.vvd
index 63029835d..aac895a74 100644
Binary files a/models/mortar/mortar_80mm.vvd and b/models/mortar/mortar_80mm.vvd differ
diff --git a/models/rotarycannon/kw/14_5mmRAC.dx80.vtx b/models/rotarycannon/kw/14_5mmRAC.dx80.vtx
new file mode 100644
index 000000000..de0cc3e04
Binary files /dev/null and b/models/rotarycannon/kw/14_5mmRAC.dx80.vtx differ
diff --git a/models/rotarycannon/kw/14_5mmRAC.dx90.vtx b/models/rotarycannon/kw/14_5mmRAC.dx90.vtx
new file mode 100644
index 000000000..4c472bed9
Binary files /dev/null and b/models/rotarycannon/kw/14_5mmRAC.dx90.vtx differ
diff --git a/models/rotarycannon/kw/14_5mmRAC.phy b/models/rotarycannon/kw/14_5mmRAC.phy
new file mode 100644
index 000000000..1909698fb
Binary files /dev/null and b/models/rotarycannon/kw/14_5mmRAC.phy differ
diff --git a/models/rotarycannon/kw/14_5mmRAC.sw.vtx b/models/rotarycannon/kw/14_5mmRAC.sw.vtx
new file mode 100644
index 000000000..8d188d392
Binary files /dev/null and b/models/rotarycannon/kw/14_5mmRAC.sw.vtx differ
diff --git a/models/rotarycannon/kw/14_5mmrac.mdl b/models/rotarycannon/kw/14_5mmrac.mdl
new file mode 100644
index 000000000..3a4d3b1e2
Binary files /dev/null and b/models/rotarycannon/kw/14_5mmrac.mdl differ
diff --git a/models/rotarycannon/kw/14_5mmrac.vvd b/models/rotarycannon/kw/14_5mmrac.vvd
new file mode 100644
index 000000000..ec638a3ad
Binary files /dev/null and b/models/rotarycannon/kw/14_5mmrac.vvd differ
diff --git a/models/rotarycannon/kw/20mmRAC.dx80.vtx b/models/rotarycannon/kw/20mmRAC.dx80.vtx
new file mode 100644
index 000000000..932e2d3a9
Binary files /dev/null and b/models/rotarycannon/kw/20mmRAC.dx80.vtx differ
diff --git a/models/rotarycannon/kw/20mmRAC.dx90.vtx b/models/rotarycannon/kw/20mmRAC.dx90.vtx
new file mode 100644
index 000000000..e41e01977
Binary files /dev/null and b/models/rotarycannon/kw/20mmRAC.dx90.vtx differ
diff --git a/models/rotarycannon/kw/20mmRAC.phy b/models/rotarycannon/kw/20mmRAC.phy
new file mode 100644
index 000000000..fcc31800c
Binary files /dev/null and b/models/rotarycannon/kw/20mmRAC.phy differ
diff --git a/models/rotarycannon/kw/20mmRAC.sw.vtx b/models/rotarycannon/kw/20mmRAC.sw.vtx
new file mode 100644
index 000000000..156f994aa
Binary files /dev/null and b/models/rotarycannon/kw/20mmRAC.sw.vtx differ
diff --git a/models/rotarycannon/kw/20mmrac.mdl b/models/rotarycannon/kw/20mmrac.mdl
new file mode 100644
index 000000000..db7264c42
Binary files /dev/null and b/models/rotarycannon/kw/20mmrac.mdl differ
diff --git a/models/rotarycannon/kw/20mmrac.vvd b/models/rotarycannon/kw/20mmrac.vvd
new file mode 100644
index 000000000..0c18aa3c5
Binary files /dev/null and b/models/rotarycannon/kw/20mmrac.vvd differ
diff --git a/models/rotarycannon/kw/30mmRAC.dx80.vtx b/models/rotarycannon/kw/30mmRAC.dx80.vtx
new file mode 100644
index 000000000..38b8410ea
Binary files /dev/null and b/models/rotarycannon/kw/30mmRAC.dx80.vtx differ
diff --git a/models/rotarycannon/kw/30mmRAC.dx90.vtx b/models/rotarycannon/kw/30mmRAC.dx90.vtx
new file mode 100644
index 000000000..1dfc37431
Binary files /dev/null and b/models/rotarycannon/kw/30mmRAC.dx90.vtx differ
diff --git a/models/rotarycannon/kw/30mmRAC.phy b/models/rotarycannon/kw/30mmRAC.phy
new file mode 100644
index 000000000..403e83e49
Binary files /dev/null and b/models/rotarycannon/kw/30mmRAC.phy differ
diff --git a/models/rotarycannon/kw/30mmRAC.sw.vtx b/models/rotarycannon/kw/30mmRAC.sw.vtx
new file mode 100644
index 000000000..fc131fa78
Binary files /dev/null and b/models/rotarycannon/kw/30mmRAC.sw.vtx differ
diff --git a/models/rotarycannon/kw/30mmrac.mdl b/models/rotarycannon/kw/30mmrac.mdl
new file mode 100644
index 000000000..be527cb47
Binary files /dev/null and b/models/rotarycannon/kw/30mmrac.mdl differ
diff --git a/models/rotarycannon/kw/30mmrac.vvd b/models/rotarycannon/kw/30mmrac.vvd
new file mode 100644
index 000000000..aa122c4c1
Binary files /dev/null and b/models/rotarycannon/kw/30mmrac.vvd differ
diff --git a/models/rotarycannon/rotarycannon_127mm.dx80.vtx b/models/rotarycannon/rotarycannon_127mm.dx80.vtx
new file mode 100644
index 000000000..8daaf6d06
Binary files /dev/null and b/models/rotarycannon/rotarycannon_127mm.dx80.vtx differ
diff --git a/models/rotarycannon/rotarycannon_127mm.dx90.vtx b/models/rotarycannon/rotarycannon_127mm.dx90.vtx
new file mode 100644
index 000000000..132a136f7
Binary files /dev/null and b/models/rotarycannon/rotarycannon_127mm.dx90.vtx differ
diff --git a/models/rotarycannon/rotarycannon_127mm.mdl b/models/rotarycannon/rotarycannon_127mm.mdl
new file mode 100644
index 000000000..a146e5e57
Binary files /dev/null and b/models/rotarycannon/rotarycannon_127mm.mdl differ
diff --git a/models/rotarycannon/rotarycannon_127mm.phy b/models/rotarycannon/rotarycannon_127mm.phy
new file mode 100644
index 000000000..fb9fe5261
Binary files /dev/null and b/models/rotarycannon/rotarycannon_127mm.phy differ
diff --git a/models/rotarycannon/rotarycannon_127mm.sw.vtx b/models/rotarycannon/rotarycannon_127mm.sw.vtx
new file mode 100644
index 000000000..c4028a6f0
Binary files /dev/null and b/models/rotarycannon/rotarycannon_127mm.sw.vtx differ
diff --git a/models/rotarycannon/rotarycannon_127mm.vvd b/models/rotarycannon/rotarycannon_127mm.vvd
new file mode 100644
index 000000000..6d453bf8c
Binary files /dev/null and b/models/rotarycannon/rotarycannon_127mm.vvd differ
diff --git a/models/rotarycannon/rotarycannon_20mm.dx80.vtx b/models/rotarycannon/rotarycannon_20mm.dx80.vtx
index c3b2ec4e5..0121034a0 100644
Binary files a/models/rotarycannon/rotarycannon_20mm.dx80.vtx and b/models/rotarycannon/rotarycannon_20mm.dx80.vtx differ
diff --git a/models/rotarycannon/rotarycannon_20mm.dx90.vtx b/models/rotarycannon/rotarycannon_20mm.dx90.vtx
index a5f2d5d55..5395774fb 100644
Binary files a/models/rotarycannon/rotarycannon_20mm.dx90.vtx and b/models/rotarycannon/rotarycannon_20mm.dx90.vtx differ
diff --git a/models/rotarycannon/rotarycannon_20mm.mdl b/models/rotarycannon/rotarycannon_20mm.mdl
index bb0bc9d9e..0c478ca93 100644
Binary files a/models/rotarycannon/rotarycannon_20mm.mdl and b/models/rotarycannon/rotarycannon_20mm.mdl differ
diff --git a/models/rotarycannon/rotarycannon_20mm.phy b/models/rotarycannon/rotarycannon_20mm.phy
index f70e802d7..51bf0db79 100644
Binary files a/models/rotarycannon/rotarycannon_20mm.phy and b/models/rotarycannon/rotarycannon_20mm.phy differ
diff --git a/models/rotarycannon/rotarycannon_20mm.sw.vtx b/models/rotarycannon/rotarycannon_20mm.sw.vtx
index b618ea855..992b80c2f 100644
Binary files a/models/rotarycannon/rotarycannon_20mm.sw.vtx and b/models/rotarycannon/rotarycannon_20mm.sw.vtx differ
diff --git a/models/rotarycannon/rotarycannon_20mm.vvd b/models/rotarycannon/rotarycannon_20mm.vvd
index 5dfc332ed..b2ecf606d 100644
Binary files a/models/rotarycannon/rotarycannon_20mm.vvd and b/models/rotarycannon/rotarycannon_20mm.vvd differ
diff --git a/models/rotarycannon/rotarycannon_30mm.dx80.vtx b/models/rotarycannon/rotarycannon_30mm.dx80.vtx
index ccee0d271..4c29be64b 100644
Binary files a/models/rotarycannon/rotarycannon_30mm.dx80.vtx and b/models/rotarycannon/rotarycannon_30mm.dx80.vtx differ
diff --git a/models/rotarycannon/rotarycannon_30mm.dx90.vtx b/models/rotarycannon/rotarycannon_30mm.dx90.vtx
index 5cf4de3b5..6cf6572f2 100644
Binary files a/models/rotarycannon/rotarycannon_30mm.dx90.vtx and b/models/rotarycannon/rotarycannon_30mm.dx90.vtx differ
diff --git a/models/rotarycannon/rotarycannon_30mm.mdl b/models/rotarycannon/rotarycannon_30mm.mdl
index d0156634b..cbe1e0d88 100644
Binary files a/models/rotarycannon/rotarycannon_30mm.mdl and b/models/rotarycannon/rotarycannon_30mm.mdl differ
diff --git a/models/rotarycannon/rotarycannon_30mm.phy b/models/rotarycannon/rotarycannon_30mm.phy
index 0627beceb..26ce62736 100644
Binary files a/models/rotarycannon/rotarycannon_30mm.phy and b/models/rotarycannon/rotarycannon_30mm.phy differ
diff --git a/models/rotarycannon/rotarycannon_30mm.sw.vtx b/models/rotarycannon/rotarycannon_30mm.sw.vtx
index 832be76e8..d9917633f 100644
Binary files a/models/rotarycannon/rotarycannon_30mm.sw.vtx and b/models/rotarycannon/rotarycannon_30mm.sw.vtx differ
diff --git a/models/rotarycannon/rotarycannon_30mm.vvd b/models/rotarycannon/rotarycannon_30mm.vvd
index f86866f2f..423b8ce01 100644
Binary files a/models/rotarycannon/rotarycannon_30mm.vvd and b/models/rotarycannon/rotarycannon_30mm.vvd differ
diff --git a/models/steeringwheels/3spokewheel.dx80.vtx b/models/steeringwheels/3spokewheel.dx80.vtx
new file mode 100644
index 000000000..86abd3fcf
Binary files /dev/null and b/models/steeringwheels/3spokewheel.dx80.vtx differ
diff --git a/models/steeringwheels/3spokewheel.dx90.vtx b/models/steeringwheels/3spokewheel.dx90.vtx
new file mode 100644
index 000000000..ffbe6fe55
Binary files /dev/null and b/models/steeringwheels/3spokewheel.dx90.vtx differ
diff --git a/models/steeringwheels/3spokewheel.mdl b/models/steeringwheels/3spokewheel.mdl
new file mode 100644
index 000000000..02bbdf025
Binary files /dev/null and b/models/steeringwheels/3spokewheel.mdl differ
diff --git a/models/steeringwheels/3spokewheel.phy b/models/steeringwheels/3spokewheel.phy
new file mode 100644
index 000000000..7b503aa21
Binary files /dev/null and b/models/steeringwheels/3spokewheel.phy differ
diff --git a/models/steeringwheels/3spokewheel.sw.vtx b/models/steeringwheels/3spokewheel.sw.vtx
new file mode 100644
index 000000000..6d6686f41
Binary files /dev/null and b/models/steeringwheels/3spokewheel.sw.vtx differ
diff --git a/models/steeringwheels/3spokewheel.vvd b/models/steeringwheels/3spokewheel.vvd
new file mode 100644
index 000000000..8c22fa372
Binary files /dev/null and b/models/steeringwheels/3spokewheel.vvd differ
diff --git a/models/steeringwheels/3spokewheel.xbox.vtx b/models/steeringwheels/3spokewheel.xbox.vtx
new file mode 100644
index 000000000..456221c74
Binary files /dev/null and b/models/steeringwheels/3spokewheel.xbox.vtx differ
diff --git a/models/steeringwheels/4spokewheel.dx80.vtx b/models/steeringwheels/4spokewheel.dx80.vtx
new file mode 100644
index 000000000..bb19305d5
Binary files /dev/null and b/models/steeringwheels/4spokewheel.dx80.vtx differ
diff --git a/models/steeringwheels/4spokewheel.dx90.vtx b/models/steeringwheels/4spokewheel.dx90.vtx
new file mode 100644
index 000000000..975877cf7
Binary files /dev/null and b/models/steeringwheels/4spokewheel.dx90.vtx differ
diff --git a/models/steeringwheels/4spokewheel.mdl b/models/steeringwheels/4spokewheel.mdl
new file mode 100644
index 000000000..618d48e1b
Binary files /dev/null and b/models/steeringwheels/4spokewheel.mdl differ
diff --git a/models/steeringwheels/4spokewheel.phy b/models/steeringwheels/4spokewheel.phy
new file mode 100644
index 000000000..19d2deece
Binary files /dev/null and b/models/steeringwheels/4spokewheel.phy differ
diff --git a/models/steeringwheels/4spokewheel.sw.vtx b/models/steeringwheels/4spokewheel.sw.vtx
new file mode 100644
index 000000000..483b38333
Binary files /dev/null and b/models/steeringwheels/4spokewheel.sw.vtx differ
diff --git a/models/steeringwheels/4spokewheel.vvd b/models/steeringwheels/4spokewheel.vvd
new file mode 100644
index 000000000..875f20272
Binary files /dev/null and b/models/steeringwheels/4spokewheel.vvd differ
diff --git a/models/steeringwheels/4spokewheel.xbox.vtx b/models/steeringwheels/4spokewheel.xbox.vtx
new file mode 100644
index 000000000..9336e7120
Binary files /dev/null and b/models/steeringwheels/4spokewheel.xbox.vtx differ
diff --git a/models/steeringwheels/buickwheel.dx80.vtx b/models/steeringwheels/buickwheel.dx80.vtx
new file mode 100644
index 000000000..c6edcd61f
Binary files /dev/null and b/models/steeringwheels/buickwheel.dx80.vtx differ
diff --git a/models/steeringwheels/buickwheel.dx90.vtx b/models/steeringwheels/buickwheel.dx90.vtx
new file mode 100644
index 000000000..1699c68ab
Binary files /dev/null and b/models/steeringwheels/buickwheel.dx90.vtx differ
diff --git a/models/steeringwheels/buickwheel.mdl b/models/steeringwheels/buickwheel.mdl
new file mode 100644
index 000000000..91bfdd1c2
Binary files /dev/null and b/models/steeringwheels/buickwheel.mdl differ
diff --git a/models/steeringwheels/buickwheel.phy b/models/steeringwheels/buickwheel.phy
new file mode 100644
index 000000000..3d308b046
Binary files /dev/null and b/models/steeringwheels/buickwheel.phy differ
diff --git a/models/steeringwheels/buickwheel.sw.vtx b/models/steeringwheels/buickwheel.sw.vtx
new file mode 100644
index 000000000..3b378cdff
Binary files /dev/null and b/models/steeringwheels/buickwheel.sw.vtx differ
diff --git a/models/steeringwheels/buickwheel.vvd b/models/steeringwheels/buickwheel.vvd
new file mode 100644
index 000000000..1bffa0652
Binary files /dev/null and b/models/steeringwheels/buickwheel.vvd differ
diff --git a/models/steeringwheels/buickwheel.xbox.vtx b/models/steeringwheels/buickwheel.xbox.vtx
new file mode 100644
index 000000000..2841ff9da
Binary files /dev/null and b/models/steeringwheels/buickwheel.xbox.vtx differ
diff --git a/models/steeringwheels/dodgewheel.dx80.vtx b/models/steeringwheels/dodgewheel.dx80.vtx
new file mode 100644
index 000000000..bd37edb0b
Binary files /dev/null and b/models/steeringwheels/dodgewheel.dx80.vtx differ
diff --git a/models/steeringwheels/dodgewheel.dx90.vtx b/models/steeringwheels/dodgewheel.dx90.vtx
new file mode 100644
index 000000000..ff41cf727
Binary files /dev/null and b/models/steeringwheels/dodgewheel.dx90.vtx differ
diff --git a/models/steeringwheels/dodgewheel.mdl b/models/steeringwheels/dodgewheel.mdl
new file mode 100644
index 000000000..5ca873dd9
Binary files /dev/null and b/models/steeringwheels/dodgewheel.mdl differ
diff --git a/models/steeringwheels/dodgewheel.phy b/models/steeringwheels/dodgewheel.phy
new file mode 100644
index 000000000..d486e84aa
Binary files /dev/null and b/models/steeringwheels/dodgewheel.phy differ
diff --git a/models/steeringwheels/dodgewheel.sw.vtx b/models/steeringwheels/dodgewheel.sw.vtx
new file mode 100644
index 000000000..01b42f374
Binary files /dev/null and b/models/steeringwheels/dodgewheel.sw.vtx differ
diff --git a/models/steeringwheels/dodgewheel.vvd b/models/steeringwheels/dodgewheel.vvd
new file mode 100644
index 000000000..c22d07a73
Binary files /dev/null and b/models/steeringwheels/dodgewheel.vvd differ
diff --git a/models/steeringwheels/dodgewheel.xbox.vtx b/models/steeringwheels/dodgewheel.xbox.vtx
new file mode 100644
index 000000000..2603319d6
Binary files /dev/null and b/models/steeringwheels/dodgewheel.xbox.vtx differ
diff --git a/models/steeringwheels/fordwheel.dx80.vtx b/models/steeringwheels/fordwheel.dx80.vtx
new file mode 100644
index 000000000..e8db6f326
Binary files /dev/null and b/models/steeringwheels/fordwheel.dx80.vtx differ
diff --git a/models/steeringwheels/fordwheel.dx90.vtx b/models/steeringwheels/fordwheel.dx90.vtx
new file mode 100644
index 000000000..d5af30594
Binary files /dev/null and b/models/steeringwheels/fordwheel.dx90.vtx differ
diff --git a/models/steeringwheels/fordwheel.mdl b/models/steeringwheels/fordwheel.mdl
new file mode 100644
index 000000000..56f0a4680
Binary files /dev/null and b/models/steeringwheels/fordwheel.mdl differ
diff --git a/models/steeringwheels/fordwheel.phy b/models/steeringwheels/fordwheel.phy
new file mode 100644
index 000000000..ca508edda
Binary files /dev/null and b/models/steeringwheels/fordwheel.phy differ
diff --git a/models/steeringwheels/fordwheel.sw.vtx b/models/steeringwheels/fordwheel.sw.vtx
new file mode 100644
index 000000000..e607fd507
Binary files /dev/null and b/models/steeringwheels/fordwheel.sw.vtx differ
diff --git a/models/steeringwheels/fordwheel.vvd b/models/steeringwheels/fordwheel.vvd
new file mode 100644
index 000000000..3eb4fb801
Binary files /dev/null and b/models/steeringwheels/fordwheel.vvd differ
diff --git a/models/steeringwheels/fordwheel.xbox.vtx b/models/steeringwheels/fordwheel.xbox.vtx
new file mode 100644
index 000000000..9f7fb9ec2
Binary files /dev/null and b/models/steeringwheels/fordwheel.xbox.vtx differ
diff --git a/models/steeringwheels/lambowheel.dx80.vtx b/models/steeringwheels/lambowheel.dx80.vtx
new file mode 100644
index 000000000..9f5cd49c3
Binary files /dev/null and b/models/steeringwheels/lambowheel.dx80.vtx differ
diff --git a/models/steeringwheels/lambowheel.dx90.vtx b/models/steeringwheels/lambowheel.dx90.vtx
new file mode 100644
index 000000000..9d0a106e1
Binary files /dev/null and b/models/steeringwheels/lambowheel.dx90.vtx differ
diff --git a/models/steeringwheels/lambowheel.mdl b/models/steeringwheels/lambowheel.mdl
new file mode 100644
index 000000000..03ad5a7af
Binary files /dev/null and b/models/steeringwheels/lambowheel.mdl differ
diff --git a/models/steeringwheels/lambowheel.phy b/models/steeringwheels/lambowheel.phy
new file mode 100644
index 000000000..a62b5b11f
Binary files /dev/null and b/models/steeringwheels/lambowheel.phy differ
diff --git a/models/steeringwheels/lambowheel.sw.vtx b/models/steeringwheels/lambowheel.sw.vtx
new file mode 100644
index 000000000..e823bb56b
Binary files /dev/null and b/models/steeringwheels/lambowheel.sw.vtx differ
diff --git a/models/steeringwheels/lambowheel.vvd b/models/steeringwheels/lambowheel.vvd
new file mode 100644
index 000000000..4533ff945
Binary files /dev/null and b/models/steeringwheels/lambowheel.vvd differ
diff --git a/models/steeringwheels/lambowheel.xbox.vtx b/models/steeringwheels/lambowheel.xbox.vtx
new file mode 100644
index 000000000..11e73fe67
Binary files /dev/null and b/models/steeringwheels/lambowheel.xbox.vtx differ
diff --git a/models/steeringwheels/truckwheel.dx80.vtx b/models/steeringwheels/truckwheel.dx80.vtx
new file mode 100644
index 000000000..0940712dd
Binary files /dev/null and b/models/steeringwheels/truckwheel.dx80.vtx differ
diff --git a/models/steeringwheels/truckwheel.dx90.vtx b/models/steeringwheels/truckwheel.dx90.vtx
new file mode 100644
index 000000000..884eb685b
Binary files /dev/null and b/models/steeringwheels/truckwheel.dx90.vtx differ
diff --git a/models/steeringwheels/truckwheel.mdl b/models/steeringwheels/truckwheel.mdl
new file mode 100644
index 000000000..b3f537799
Binary files /dev/null and b/models/steeringwheels/truckwheel.mdl differ
diff --git a/models/steeringwheels/truckwheel.phy b/models/steeringwheels/truckwheel.phy
new file mode 100644
index 000000000..528d16f51
Binary files /dev/null and b/models/steeringwheels/truckwheel.phy differ
diff --git a/models/steeringwheels/truckwheel.sw.vtx b/models/steeringwheels/truckwheel.sw.vtx
new file mode 100644
index 000000000..d05dbd733
Binary files /dev/null and b/models/steeringwheels/truckwheel.sw.vtx differ
diff --git a/models/steeringwheels/truckwheel.vvd b/models/steeringwheels/truckwheel.vvd
new file mode 100644
index 000000000..b52d32501
Binary files /dev/null and b/models/steeringwheels/truckwheel.vvd differ
diff --git a/models/steeringwheels/truckwheel.xbox.vtx b/models/steeringwheels/truckwheel.xbox.vtx
new file mode 100644
index 000000000..d3e3b0ac2
Binary files /dev/null and b/models/steeringwheels/truckwheel.xbox.vtx differ
diff --git a/models/tankgun/tankgun_100mm.dx80.vtx b/models/tankgun/tankgun_100mm.dx80.vtx
index b182aeb41..5fee718f8 100644
Binary files a/models/tankgun/tankgun_100mm.dx80.vtx and b/models/tankgun/tankgun_100mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_100mm.dx90.vtx b/models/tankgun/tankgun_100mm.dx90.vtx
index 6bf7d781e..a6c5c1854 100644
Binary files a/models/tankgun/tankgun_100mm.dx90.vtx and b/models/tankgun/tankgun_100mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_100mm.mdl b/models/tankgun/tankgun_100mm.mdl
index a3cedf9f6..cbe51f30e 100644
Binary files a/models/tankgun/tankgun_100mm.mdl and b/models/tankgun/tankgun_100mm.mdl differ
diff --git a/models/tankgun/tankgun_100mm.phy b/models/tankgun/tankgun_100mm.phy
index d886ba0cc..ca9408e94 100644
Binary files a/models/tankgun/tankgun_100mm.phy and b/models/tankgun/tankgun_100mm.phy differ
diff --git a/models/tankgun/tankgun_100mm.sw.vtx b/models/tankgun/tankgun_100mm.sw.vtx
index 4471d7748..fca8bb890 100644
Binary files a/models/tankgun/tankgun_100mm.sw.vtx and b/models/tankgun/tankgun_100mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_100mm.vvd b/models/tankgun/tankgun_100mm.vvd
index def804bbc..60a431873 100644
Binary files a/models/tankgun/tankgun_100mm.vvd and b/models/tankgun/tankgun_100mm.vvd differ
diff --git a/models/tankgun/tankgun_120mm.dx80.vtx b/models/tankgun/tankgun_120mm.dx80.vtx
index 2f81cabf8..52e564cca 100644
Binary files a/models/tankgun/tankgun_120mm.dx80.vtx and b/models/tankgun/tankgun_120mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_120mm.dx90.vtx b/models/tankgun/tankgun_120mm.dx90.vtx
index 363b6753d..fc86595a6 100644
Binary files a/models/tankgun/tankgun_120mm.dx90.vtx and b/models/tankgun/tankgun_120mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_120mm.mdl b/models/tankgun/tankgun_120mm.mdl
index d99ecb2c9..1b4215ea6 100644
Binary files a/models/tankgun/tankgun_120mm.mdl and b/models/tankgun/tankgun_120mm.mdl differ
diff --git a/models/tankgun/tankgun_120mm.phy b/models/tankgun/tankgun_120mm.phy
index c684f4654..14e29ce29 100644
Binary files a/models/tankgun/tankgun_120mm.phy and b/models/tankgun/tankgun_120mm.phy differ
diff --git a/models/tankgun/tankgun_120mm.sw.vtx b/models/tankgun/tankgun_120mm.sw.vtx
index d0588c01e..2f5d64562 100644
Binary files a/models/tankgun/tankgun_120mm.sw.vtx and b/models/tankgun/tankgun_120mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_120mm.vvd b/models/tankgun/tankgun_120mm.vvd
index 446f54613..64a4bfaff 100644
Binary files a/models/tankgun/tankgun_120mm.vvd and b/models/tankgun/tankgun_120mm.vvd differ
diff --git a/models/tankgun/tankgun_140mm.dx80.vtx b/models/tankgun/tankgun_140mm.dx80.vtx
index f4f3491cd..60a5ac0a5 100644
Binary files a/models/tankgun/tankgun_140mm.dx80.vtx and b/models/tankgun/tankgun_140mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_140mm.dx90.vtx b/models/tankgun/tankgun_140mm.dx90.vtx
index 93d2a9b5d..f49f0cae4 100644
Binary files a/models/tankgun/tankgun_140mm.dx90.vtx and b/models/tankgun/tankgun_140mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_140mm.mdl b/models/tankgun/tankgun_140mm.mdl
index cf820f847..e7ec5328f 100644
Binary files a/models/tankgun/tankgun_140mm.mdl and b/models/tankgun/tankgun_140mm.mdl differ
diff --git a/models/tankgun/tankgun_140mm.phy b/models/tankgun/tankgun_140mm.phy
index a6467bca1..decc8276f 100644
Binary files a/models/tankgun/tankgun_140mm.phy and b/models/tankgun/tankgun_140mm.phy differ
diff --git a/models/tankgun/tankgun_140mm.sw.vtx b/models/tankgun/tankgun_140mm.sw.vtx
index c63310931..ccc8dd660 100644
Binary files a/models/tankgun/tankgun_140mm.sw.vtx and b/models/tankgun/tankgun_140mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_140mm.vvd b/models/tankgun/tankgun_140mm.vvd
index b6ed6e02c..83274d8f0 100644
Binary files a/models/tankgun/tankgun_140mm.vvd and b/models/tankgun/tankgun_140mm.vvd differ
diff --git a/models/tankgun/tankgun_170mm.dx80.vtx b/models/tankgun/tankgun_170mm.dx80.vtx
new file mode 100644
index 000000000..67ac3b50d
Binary files /dev/null and b/models/tankgun/tankgun_170mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_170mm.dx90.vtx b/models/tankgun/tankgun_170mm.dx90.vtx
new file mode 100644
index 000000000..a7e8875d0
Binary files /dev/null and b/models/tankgun/tankgun_170mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_170mm.mdl b/models/tankgun/tankgun_170mm.mdl
new file mode 100644
index 000000000..05ff6eddc
Binary files /dev/null and b/models/tankgun/tankgun_170mm.mdl differ
diff --git a/models/tankgun/tankgun_170mm.phy b/models/tankgun/tankgun_170mm.phy
new file mode 100644
index 000000000..a04ae0538
Binary files /dev/null and b/models/tankgun/tankgun_170mm.phy differ
diff --git a/models/tankgun/tankgun_170mm.sw.vtx b/models/tankgun/tankgun_170mm.sw.vtx
new file mode 100644
index 000000000..acbf905cc
Binary files /dev/null and b/models/tankgun/tankgun_170mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_170mm.vvd b/models/tankgun/tankgun_170mm.vvd
new file mode 100644
index 000000000..1ef5e37b1
Binary files /dev/null and b/models/tankgun/tankgun_170mm.vvd differ
diff --git a/models/tankgun/tankgun_37mm.dx80.vtx b/models/tankgun/tankgun_37mm.dx80.vtx
new file mode 100644
index 000000000..cf563f92f
Binary files /dev/null and b/models/tankgun/tankgun_37mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_37mm.dx90.vtx b/models/tankgun/tankgun_37mm.dx90.vtx
new file mode 100644
index 000000000..d8035bf5e
Binary files /dev/null and b/models/tankgun/tankgun_37mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_37mm.mdl b/models/tankgun/tankgun_37mm.mdl
new file mode 100644
index 000000000..54f6caf48
Binary files /dev/null and b/models/tankgun/tankgun_37mm.mdl differ
diff --git a/models/tankgun/tankgun_37mm.phy b/models/tankgun/tankgun_37mm.phy
new file mode 100644
index 000000000..507aa1251
Binary files /dev/null and b/models/tankgun/tankgun_37mm.phy differ
diff --git a/models/tankgun/tankgun_37mm.sw.vtx b/models/tankgun/tankgun_37mm.sw.vtx
new file mode 100644
index 000000000..618ef2734
Binary files /dev/null and b/models/tankgun/tankgun_37mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_37mm.vvd b/models/tankgun/tankgun_37mm.vvd
new file mode 100644
index 000000000..f4ea740ab
Binary files /dev/null and b/models/tankgun/tankgun_37mm.vvd differ
diff --git a/models/tankgun/tankgun_50mm.dx80.vtx b/models/tankgun/tankgun_50mm.dx80.vtx
index abbe089a2..b2566624c 100644
Binary files a/models/tankgun/tankgun_50mm.dx80.vtx and b/models/tankgun/tankgun_50mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_50mm.dx90.vtx b/models/tankgun/tankgun_50mm.dx90.vtx
index 612ebd8e6..1aab0eff5 100644
Binary files a/models/tankgun/tankgun_50mm.dx90.vtx and b/models/tankgun/tankgun_50mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_50mm.mdl b/models/tankgun/tankgun_50mm.mdl
index 240bf411d..f72bcb4bd 100644
Binary files a/models/tankgun/tankgun_50mm.mdl and b/models/tankgun/tankgun_50mm.mdl differ
diff --git a/models/tankgun/tankgun_50mm.phy b/models/tankgun/tankgun_50mm.phy
index fc67b55ba..654fa09e6 100644
Binary files a/models/tankgun/tankgun_50mm.phy and b/models/tankgun/tankgun_50mm.phy differ
diff --git a/models/tankgun/tankgun_50mm.sw.vtx b/models/tankgun/tankgun_50mm.sw.vtx
index 5d584ae07..b8fe25b05 100644
Binary files a/models/tankgun/tankgun_50mm.sw.vtx and b/models/tankgun/tankgun_50mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_50mm.vvd b/models/tankgun/tankgun_50mm.vvd
index c798d7d9f..714f13697 100644
Binary files a/models/tankgun/tankgun_50mm.vvd and b/models/tankgun/tankgun_50mm.vvd differ
diff --git a/models/tankgun/tankgun_75mm.dx80.vtx b/models/tankgun/tankgun_75mm.dx80.vtx
index e80b2a87c..172f89ccf 100644
Binary files a/models/tankgun/tankgun_75mm.dx80.vtx and b/models/tankgun/tankgun_75mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_75mm.dx90.vtx b/models/tankgun/tankgun_75mm.dx90.vtx
index e4c1e3270..dd9fc02a8 100644
Binary files a/models/tankgun/tankgun_75mm.dx90.vtx and b/models/tankgun/tankgun_75mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_75mm.mdl b/models/tankgun/tankgun_75mm.mdl
index 4c19ac6db..a761f302b 100644
Binary files a/models/tankgun/tankgun_75mm.mdl and b/models/tankgun/tankgun_75mm.mdl differ
diff --git a/models/tankgun/tankgun_75mm.phy b/models/tankgun/tankgun_75mm.phy
index 072431386..d4a94f0d2 100644
Binary files a/models/tankgun/tankgun_75mm.phy and b/models/tankgun/tankgun_75mm.phy differ
diff --git a/models/tankgun/tankgun_75mm.sw.vtx b/models/tankgun/tankgun_75mm.sw.vtx
index 4f0431120..b603ed75a 100644
Binary files a/models/tankgun/tankgun_75mm.sw.vtx and b/models/tankgun/tankgun_75mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_75mm.vvd b/models/tankgun/tankgun_75mm.vvd
index 0bc935e31..b0d586850 100644
Binary files a/models/tankgun/tankgun_75mm.vvd and b/models/tankgun/tankgun_75mm.vvd differ
diff --git a/models/tankgun/tankgun_AL_100mm.dx80.vtx b/models/tankgun/tankgun_AL_100mm.dx80.vtx
deleted file mode 100644
index 94f66b785..000000000
Binary files a/models/tankgun/tankgun_AL_100mm.dx80.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_100mm.dx90.vtx b/models/tankgun/tankgun_AL_100mm.dx90.vtx
deleted file mode 100644
index 574e8d802..000000000
Binary files a/models/tankgun/tankgun_AL_100mm.dx90.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_100mm.sw.vtx b/models/tankgun/tankgun_AL_100mm.sw.vtx
deleted file mode 100644
index d369c88d7..000000000
Binary files a/models/tankgun/tankgun_AL_100mm.sw.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_120mm.dx80.vtx b/models/tankgun/tankgun_AL_120mm.dx80.vtx
deleted file mode 100644
index c8623ba02..000000000
Binary files a/models/tankgun/tankgun_AL_120mm.dx80.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_120mm.dx90.vtx b/models/tankgun/tankgun_AL_120mm.dx90.vtx
deleted file mode 100644
index b0b29acbd..000000000
Binary files a/models/tankgun/tankgun_AL_120mm.dx90.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_120mm.sw.vtx b/models/tankgun/tankgun_AL_120mm.sw.vtx
deleted file mode 100644
index 785d39e3f..000000000
Binary files a/models/tankgun/tankgun_AL_120mm.sw.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_140mm.dx80.vtx b/models/tankgun/tankgun_AL_140mm.dx80.vtx
deleted file mode 100644
index e57076501..000000000
Binary files a/models/tankgun/tankgun_AL_140mm.dx80.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_140mm.dx90.vtx b/models/tankgun/tankgun_AL_140mm.dx90.vtx
deleted file mode 100644
index 9cf1da43b..000000000
Binary files a/models/tankgun/tankgun_AL_140mm.dx90.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_140mm.sw.vtx b/models/tankgun/tankgun_AL_140mm.sw.vtx
deleted file mode 100644
index 35e5a9b0a..000000000
Binary files a/models/tankgun/tankgun_AL_140mm.sw.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_170mm.dx80.vtx b/models/tankgun/tankgun_AL_170mm.dx80.vtx
new file mode 100644
index 000000000..7f9486ccd
Binary files /dev/null and b/models/tankgun/tankgun_AL_170mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_AL_170mm.dx90.vtx b/models/tankgun/tankgun_AL_170mm.dx90.vtx
new file mode 100644
index 000000000..5316860ed
Binary files /dev/null and b/models/tankgun/tankgun_AL_170mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_AL_170mm.phy b/models/tankgun/tankgun_AL_170mm.phy
new file mode 100644
index 000000000..9b21bc2d2
Binary files /dev/null and b/models/tankgun/tankgun_AL_170mm.phy differ
diff --git a/models/tankgun/tankgun_AL_170mm.sw.vtx b/models/tankgun/tankgun_AL_170mm.sw.vtx
new file mode 100644
index 000000000..4aba61392
Binary files /dev/null and b/models/tankgun/tankgun_AL_170mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_AL_50mm.dx80.vtx b/models/tankgun/tankgun_AL_50mm.dx80.vtx
deleted file mode 100644
index 71aa0d798..000000000
Binary files a/models/tankgun/tankgun_AL_50mm.dx80.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_50mm.dx90.vtx b/models/tankgun/tankgun_AL_50mm.dx90.vtx
deleted file mode 100644
index cd76900f1..000000000
Binary files a/models/tankgun/tankgun_AL_50mm.dx90.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_50mm.sw.vtx b/models/tankgun/tankgun_AL_50mm.sw.vtx
deleted file mode 100644
index ab4b4a23d..000000000
Binary files a/models/tankgun/tankgun_AL_50mm.sw.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_75mm.dx80.vtx b/models/tankgun/tankgun_AL_75mm.dx80.vtx
deleted file mode 100644
index 13572e1d1..000000000
Binary files a/models/tankgun/tankgun_AL_75mm.dx80.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_75mm.dx90.vtx b/models/tankgun/tankgun_AL_75mm.dx90.vtx
deleted file mode 100644
index dc6ad3822..000000000
Binary files a/models/tankgun/tankgun_AL_75mm.dx90.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_AL_75mm.sw.vtx b/models/tankgun/tankgun_AL_75mm.sw.vtx
deleted file mode 100644
index 7587d27b5..000000000
Binary files a/models/tankgun/tankgun_AL_75mm.sw.vtx and /dev/null differ
diff --git a/models/tankgun/tankgun_al_100mm.dx80.vtx b/models/tankgun/tankgun_al_100mm.dx80.vtx
new file mode 100644
index 000000000..620b99b30
Binary files /dev/null and b/models/tankgun/tankgun_al_100mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_al_100mm.dx90.vtx b/models/tankgun/tankgun_al_100mm.dx90.vtx
new file mode 100644
index 000000000..3876d4c3c
Binary files /dev/null and b/models/tankgun/tankgun_al_100mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_al_100mm.mdl b/models/tankgun/tankgun_al_100mm.mdl
index a6a638bb9..26f9a1f13 100644
Binary files a/models/tankgun/tankgun_al_100mm.mdl and b/models/tankgun/tankgun_al_100mm.mdl differ
diff --git a/models/tankgun/tankgun_AL_100mm.phy b/models/tankgun/tankgun_al_100mm.phy
similarity index 100%
rename from models/tankgun/tankgun_AL_100mm.phy
rename to models/tankgun/tankgun_al_100mm.phy
diff --git a/models/tankgun/tankgun_al_100mm.sw.vtx b/models/tankgun/tankgun_al_100mm.sw.vtx
new file mode 100644
index 000000000..2d552805c
Binary files /dev/null and b/models/tankgun/tankgun_al_100mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_al_100mm.vvd b/models/tankgun/tankgun_al_100mm.vvd
index 88de7f982..25a95b143 100644
Binary files a/models/tankgun/tankgun_al_100mm.vvd and b/models/tankgun/tankgun_al_100mm.vvd differ
diff --git a/models/tankgun/tankgun_al_120mm.dx80.vtx b/models/tankgun/tankgun_al_120mm.dx80.vtx
new file mode 100644
index 000000000..44dbaaca6
Binary files /dev/null and b/models/tankgun/tankgun_al_120mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_al_120mm.dx90.vtx b/models/tankgun/tankgun_al_120mm.dx90.vtx
new file mode 100644
index 000000000..1885a2774
Binary files /dev/null and b/models/tankgun/tankgun_al_120mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_al_120mm.mdl b/models/tankgun/tankgun_al_120mm.mdl
index 44d7862bf..a1b8df60c 100644
Binary files a/models/tankgun/tankgun_al_120mm.mdl and b/models/tankgun/tankgun_al_120mm.mdl differ
diff --git a/models/tankgun/tankgun_AL_120mm.phy b/models/tankgun/tankgun_al_120mm.phy
similarity index 100%
rename from models/tankgun/tankgun_AL_120mm.phy
rename to models/tankgun/tankgun_al_120mm.phy
diff --git a/models/tankgun/tankgun_al_120mm.sw.vtx b/models/tankgun/tankgun_al_120mm.sw.vtx
new file mode 100644
index 000000000..9bc178b13
Binary files /dev/null and b/models/tankgun/tankgun_al_120mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_al_120mm.vvd b/models/tankgun/tankgun_al_120mm.vvd
index d5fa6f1b8..41049057e 100644
Binary files a/models/tankgun/tankgun_al_120mm.vvd and b/models/tankgun/tankgun_al_120mm.vvd differ
diff --git a/models/tankgun/tankgun_al_140mm.dx80.vtx b/models/tankgun/tankgun_al_140mm.dx80.vtx
new file mode 100644
index 000000000..d38532b54
Binary files /dev/null and b/models/tankgun/tankgun_al_140mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_al_140mm.dx90.vtx b/models/tankgun/tankgun_al_140mm.dx90.vtx
new file mode 100644
index 000000000..ba2f5f96b
Binary files /dev/null and b/models/tankgun/tankgun_al_140mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_al_140mm.mdl b/models/tankgun/tankgun_al_140mm.mdl
index ef40261f5..bedeeffc2 100644
Binary files a/models/tankgun/tankgun_al_140mm.mdl and b/models/tankgun/tankgun_al_140mm.mdl differ
diff --git a/models/tankgun/tankgun_AL_140mm.phy b/models/tankgun/tankgun_al_140mm.phy
similarity index 100%
rename from models/tankgun/tankgun_AL_140mm.phy
rename to models/tankgun/tankgun_al_140mm.phy
diff --git a/models/tankgun/tankgun_al_140mm.sw.vtx b/models/tankgun/tankgun_al_140mm.sw.vtx
new file mode 100644
index 000000000..3452c31ea
Binary files /dev/null and b/models/tankgun/tankgun_al_140mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_al_140mm.vvd b/models/tankgun/tankgun_al_140mm.vvd
index 47dc0dc96..028756413 100644
Binary files a/models/tankgun/tankgun_al_140mm.vvd and b/models/tankgun/tankgun_al_140mm.vvd differ
diff --git a/models/tankgun/tankgun_al_170mm.mdl b/models/tankgun/tankgun_al_170mm.mdl
new file mode 100644
index 000000000..53d3f20e7
Binary files /dev/null and b/models/tankgun/tankgun_al_170mm.mdl differ
diff --git a/models/tankgun/tankgun_al_170mm.vvd b/models/tankgun/tankgun_al_170mm.vvd
new file mode 100644
index 000000000..b986f5839
Binary files /dev/null and b/models/tankgun/tankgun_al_170mm.vvd differ
diff --git a/models/tankgun/tankgun_al_50mm.dx80.vtx b/models/tankgun/tankgun_al_50mm.dx80.vtx
new file mode 100644
index 000000000..e9516326f
Binary files /dev/null and b/models/tankgun/tankgun_al_50mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_al_50mm.dx90.vtx b/models/tankgun/tankgun_al_50mm.dx90.vtx
new file mode 100644
index 000000000..700386d06
Binary files /dev/null and b/models/tankgun/tankgun_al_50mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_al_50mm.mdl b/models/tankgun/tankgun_al_50mm.mdl
index 4e7bea24e..626e65a93 100644
Binary files a/models/tankgun/tankgun_al_50mm.mdl and b/models/tankgun/tankgun_al_50mm.mdl differ
diff --git a/models/tankgun/tankgun_AL_50mm.phy b/models/tankgun/tankgun_al_50mm.phy
similarity index 100%
rename from models/tankgun/tankgun_AL_50mm.phy
rename to models/tankgun/tankgun_al_50mm.phy
diff --git a/models/tankgun/tankgun_al_50mm.sw.vtx b/models/tankgun/tankgun_al_50mm.sw.vtx
new file mode 100644
index 000000000..b1ff57bdd
Binary files /dev/null and b/models/tankgun/tankgun_al_50mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_al_50mm.vvd b/models/tankgun/tankgun_al_50mm.vvd
index 66ab9080a..12791852f 100644
Binary files a/models/tankgun/tankgun_al_50mm.vvd and b/models/tankgun/tankgun_al_50mm.vvd differ
diff --git a/models/tankgun/tankgun_al_75mm.dx80.vtx b/models/tankgun/tankgun_al_75mm.dx80.vtx
new file mode 100644
index 000000000..54f213880
Binary files /dev/null and b/models/tankgun/tankgun_al_75mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_al_75mm.dx90.vtx b/models/tankgun/tankgun_al_75mm.dx90.vtx
new file mode 100644
index 000000000..949e9df79
Binary files /dev/null and b/models/tankgun/tankgun_al_75mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_al_75mm.mdl b/models/tankgun/tankgun_al_75mm.mdl
index 89d180876..c56d601aa 100644
Binary files a/models/tankgun/tankgun_al_75mm.mdl and b/models/tankgun/tankgun_al_75mm.mdl differ
diff --git a/models/tankgun/tankgun_AL_75mm.phy b/models/tankgun/tankgun_al_75mm.phy
similarity index 100%
rename from models/tankgun/tankgun_AL_75mm.phy
rename to models/tankgun/tankgun_al_75mm.phy
diff --git a/models/tankgun/tankgun_al_75mm.sw.vtx b/models/tankgun/tankgun_al_75mm.sw.vtx
new file mode 100644
index 000000000..fe5605cbc
Binary files /dev/null and b/models/tankgun/tankgun_al_75mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_al_75mm.vvd b/models/tankgun/tankgun_al_75mm.vvd
index 87932b0a8..7ae59b1c9 100644
Binary files a/models/tankgun/tankgun_al_75mm.vvd and b/models/tankgun/tankgun_al_75mm.vvd differ
diff --git a/models/tankgun/tankgun_short_100mm.dx80.vtx b/models/tankgun/tankgun_short_100mm.dx80.vtx
new file mode 100644
index 000000000..87f6df61c
Binary files /dev/null and b/models/tankgun/tankgun_short_100mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_short_100mm.dx90.vtx b/models/tankgun/tankgun_short_100mm.dx90.vtx
new file mode 100644
index 000000000..8a045bc64
Binary files /dev/null and b/models/tankgun/tankgun_short_100mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_short_100mm.mdl b/models/tankgun/tankgun_short_100mm.mdl
new file mode 100644
index 000000000..83d3251ce
Binary files /dev/null and b/models/tankgun/tankgun_short_100mm.mdl differ
diff --git a/models/tankgun/tankgun_short_100mm.phy b/models/tankgun/tankgun_short_100mm.phy
new file mode 100644
index 000000000..9dd7de847
Binary files /dev/null and b/models/tankgun/tankgun_short_100mm.phy differ
diff --git a/models/tankgun/tankgun_short_100mm.sw.vtx b/models/tankgun/tankgun_short_100mm.sw.vtx
new file mode 100644
index 000000000..25bee894d
Binary files /dev/null and b/models/tankgun/tankgun_short_100mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_short_100mm.vvd b/models/tankgun/tankgun_short_100mm.vvd
new file mode 100644
index 000000000..10fd21057
Binary files /dev/null and b/models/tankgun/tankgun_short_100mm.vvd differ
diff --git a/models/tankgun/tankgun_short_120mm.dx80.vtx b/models/tankgun/tankgun_short_120mm.dx80.vtx
new file mode 100644
index 000000000..410602faf
Binary files /dev/null and b/models/tankgun/tankgun_short_120mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_short_120mm.dx90.vtx b/models/tankgun/tankgun_short_120mm.dx90.vtx
new file mode 100644
index 000000000..226a4d92e
Binary files /dev/null and b/models/tankgun/tankgun_short_120mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_short_120mm.mdl b/models/tankgun/tankgun_short_120mm.mdl
new file mode 100644
index 000000000..f01645da3
Binary files /dev/null and b/models/tankgun/tankgun_short_120mm.mdl differ
diff --git a/models/tankgun/tankgun_short_120mm.phy b/models/tankgun/tankgun_short_120mm.phy
new file mode 100644
index 000000000..07542b804
Binary files /dev/null and b/models/tankgun/tankgun_short_120mm.phy differ
diff --git a/models/tankgun/tankgun_short_120mm.sw.vtx b/models/tankgun/tankgun_short_120mm.sw.vtx
new file mode 100644
index 000000000..ee23ba395
Binary files /dev/null and b/models/tankgun/tankgun_short_120mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_short_120mm.vvd b/models/tankgun/tankgun_short_120mm.vvd
new file mode 100644
index 000000000..c9b6e506c
Binary files /dev/null and b/models/tankgun/tankgun_short_120mm.vvd differ
diff --git a/models/tankgun/tankgun_short_140mm.dx80.vtx b/models/tankgun/tankgun_short_140mm.dx80.vtx
new file mode 100644
index 000000000..8f8fcd207
Binary files /dev/null and b/models/tankgun/tankgun_short_140mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_short_140mm.dx90.vtx b/models/tankgun/tankgun_short_140mm.dx90.vtx
new file mode 100644
index 000000000..11490fcda
Binary files /dev/null and b/models/tankgun/tankgun_short_140mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_short_140mm.mdl b/models/tankgun/tankgun_short_140mm.mdl
new file mode 100644
index 000000000..4f7abc474
Binary files /dev/null and b/models/tankgun/tankgun_short_140mm.mdl differ
diff --git a/models/tankgun/tankgun_short_140mm.phy b/models/tankgun/tankgun_short_140mm.phy
new file mode 100644
index 000000000..4e6dee7af
Binary files /dev/null and b/models/tankgun/tankgun_short_140mm.phy differ
diff --git a/models/tankgun/tankgun_short_140mm.sw.vtx b/models/tankgun/tankgun_short_140mm.sw.vtx
new file mode 100644
index 000000000..9fcb29766
Binary files /dev/null and b/models/tankgun/tankgun_short_140mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_short_140mm.vvd b/models/tankgun/tankgun_short_140mm.vvd
new file mode 100644
index 000000000..7d7ac2be0
Binary files /dev/null and b/models/tankgun/tankgun_short_140mm.vvd differ
diff --git a/models/tankgun/tankgun_short_37mm.dx80.vtx b/models/tankgun/tankgun_short_37mm.dx80.vtx
new file mode 100644
index 000000000..864212c2e
Binary files /dev/null and b/models/tankgun/tankgun_short_37mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_short_37mm.dx90.vtx b/models/tankgun/tankgun_short_37mm.dx90.vtx
new file mode 100644
index 000000000..e4d5e5244
Binary files /dev/null and b/models/tankgun/tankgun_short_37mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_short_37mm.mdl b/models/tankgun/tankgun_short_37mm.mdl
new file mode 100644
index 000000000..7e56b97c9
Binary files /dev/null and b/models/tankgun/tankgun_short_37mm.mdl differ
diff --git a/models/tankgun/tankgun_short_37mm.phy b/models/tankgun/tankgun_short_37mm.phy
new file mode 100644
index 000000000..3890c2d61
Binary files /dev/null and b/models/tankgun/tankgun_short_37mm.phy differ
diff --git a/models/tankgun/tankgun_short_37mm.sw.vtx b/models/tankgun/tankgun_short_37mm.sw.vtx
new file mode 100644
index 000000000..fe72d550a
Binary files /dev/null and b/models/tankgun/tankgun_short_37mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_short_37mm.vvd b/models/tankgun/tankgun_short_37mm.vvd
new file mode 100644
index 000000000..1fad32bde
Binary files /dev/null and b/models/tankgun/tankgun_short_37mm.vvd differ
diff --git a/models/tankgun/tankgun_short_50mm.dx80.vtx b/models/tankgun/tankgun_short_50mm.dx80.vtx
new file mode 100644
index 000000000..17e72111d
Binary files /dev/null and b/models/tankgun/tankgun_short_50mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_short_50mm.dx90.vtx b/models/tankgun/tankgun_short_50mm.dx90.vtx
new file mode 100644
index 000000000..7c743cd39
Binary files /dev/null and b/models/tankgun/tankgun_short_50mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_short_50mm.mdl b/models/tankgun/tankgun_short_50mm.mdl
new file mode 100644
index 000000000..8c6355bd2
Binary files /dev/null and b/models/tankgun/tankgun_short_50mm.mdl differ
diff --git a/models/tankgun/tankgun_short_50mm.phy b/models/tankgun/tankgun_short_50mm.phy
new file mode 100644
index 000000000..e6460c76b
Binary files /dev/null and b/models/tankgun/tankgun_short_50mm.phy differ
diff --git a/models/tankgun/tankgun_short_50mm.sw.vtx b/models/tankgun/tankgun_short_50mm.sw.vtx
new file mode 100644
index 000000000..3ef73bacc
Binary files /dev/null and b/models/tankgun/tankgun_short_50mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_short_50mm.vvd b/models/tankgun/tankgun_short_50mm.vvd
new file mode 100644
index 000000000..b8450fe3c
Binary files /dev/null and b/models/tankgun/tankgun_short_50mm.vvd differ
diff --git a/models/tankgun/tankgun_short_75mm.dx80.vtx b/models/tankgun/tankgun_short_75mm.dx80.vtx
new file mode 100644
index 000000000..df2de2287
Binary files /dev/null and b/models/tankgun/tankgun_short_75mm.dx80.vtx differ
diff --git a/models/tankgun/tankgun_short_75mm.dx90.vtx b/models/tankgun/tankgun_short_75mm.dx90.vtx
new file mode 100644
index 000000000..92f8b22b0
Binary files /dev/null and b/models/tankgun/tankgun_short_75mm.dx90.vtx differ
diff --git a/models/tankgun/tankgun_short_75mm.mdl b/models/tankgun/tankgun_short_75mm.mdl
new file mode 100644
index 000000000..3d2bba116
Binary files /dev/null and b/models/tankgun/tankgun_short_75mm.mdl differ
diff --git a/models/tankgun/tankgun_short_75mm.phy b/models/tankgun/tankgun_short_75mm.phy
new file mode 100644
index 000000000..108c0327f
Binary files /dev/null and b/models/tankgun/tankgun_short_75mm.phy differ
diff --git a/models/tankgun/tankgun_short_75mm.sw.vtx b/models/tankgun/tankgun_short_75mm.sw.vtx
new file mode 100644
index 000000000..24b7989d1
Binary files /dev/null and b/models/tankgun/tankgun_short_75mm.sw.vtx differ
diff --git a/models/tankgun/tankgun_short_75mm.vvd b/models/tankgun/tankgun_short_75mm.vvd
new file mode 100644
index 000000000..6809b29f5
Binary files /dev/null and b/models/tankgun/tankgun_short_75mm.vvd differ
diff --git a/models/tankgun_old/tankgun_100mm.dx80.vtx b/models/tankgun_old/tankgun_100mm.dx80.vtx
new file mode 100644
index 000000000..b182aeb41
Binary files /dev/null and b/models/tankgun_old/tankgun_100mm.dx80.vtx differ
diff --git a/models/tankgun_old/tankgun_100mm.dx90.vtx b/models/tankgun_old/tankgun_100mm.dx90.vtx
new file mode 100644
index 000000000..6bf7d781e
Binary files /dev/null and b/models/tankgun_old/tankgun_100mm.dx90.vtx differ
diff --git a/models/tankgun_old/tankgun_100mm.mdl b/models/tankgun_old/tankgun_100mm.mdl
new file mode 100644
index 000000000..a3cedf9f6
Binary files /dev/null and b/models/tankgun_old/tankgun_100mm.mdl differ
diff --git a/models/tankgun_old/tankgun_100mm.phy b/models/tankgun_old/tankgun_100mm.phy
new file mode 100644
index 000000000..d886ba0cc
Binary files /dev/null and b/models/tankgun_old/tankgun_100mm.phy differ
diff --git a/models/tankgun_old/tankgun_100mm.sw.vtx b/models/tankgun_old/tankgun_100mm.sw.vtx
new file mode 100644
index 000000000..4471d7748
Binary files /dev/null and b/models/tankgun_old/tankgun_100mm.sw.vtx differ
diff --git a/models/tankgun_old/tankgun_100mm.vvd b/models/tankgun_old/tankgun_100mm.vvd
new file mode 100644
index 000000000..def804bbc
Binary files /dev/null and b/models/tankgun_old/tankgun_100mm.vvd differ
diff --git a/models/tankgun_old/tankgun_120mm.dx80.vtx b/models/tankgun_old/tankgun_120mm.dx80.vtx
new file mode 100644
index 000000000..2f81cabf8
Binary files /dev/null and b/models/tankgun_old/tankgun_120mm.dx80.vtx differ
diff --git a/models/tankgun_old/tankgun_120mm.dx90.vtx b/models/tankgun_old/tankgun_120mm.dx90.vtx
new file mode 100644
index 000000000..363b6753d
Binary files /dev/null and b/models/tankgun_old/tankgun_120mm.dx90.vtx differ
diff --git a/models/tankgun_old/tankgun_120mm.mdl b/models/tankgun_old/tankgun_120mm.mdl
new file mode 100644
index 000000000..d99ecb2c9
Binary files /dev/null and b/models/tankgun_old/tankgun_120mm.mdl differ
diff --git a/models/tankgun_old/tankgun_120mm.phy b/models/tankgun_old/tankgun_120mm.phy
new file mode 100644
index 000000000..c684f4654
Binary files /dev/null and b/models/tankgun_old/tankgun_120mm.phy differ
diff --git a/models/tankgun_old/tankgun_120mm.sw.vtx b/models/tankgun_old/tankgun_120mm.sw.vtx
new file mode 100644
index 000000000..d0588c01e
Binary files /dev/null and b/models/tankgun_old/tankgun_120mm.sw.vtx differ
diff --git a/models/tankgun_old/tankgun_120mm.vvd b/models/tankgun_old/tankgun_120mm.vvd
new file mode 100644
index 000000000..446f54613
Binary files /dev/null and b/models/tankgun_old/tankgun_120mm.vvd differ
diff --git a/models/tankgun_old/tankgun_140mm.dx80.vtx b/models/tankgun_old/tankgun_140mm.dx80.vtx
new file mode 100644
index 000000000..f4f3491cd
Binary files /dev/null and b/models/tankgun_old/tankgun_140mm.dx80.vtx differ
diff --git a/models/tankgun_old/tankgun_140mm.dx90.vtx b/models/tankgun_old/tankgun_140mm.dx90.vtx
new file mode 100644
index 000000000..93d2a9b5d
Binary files /dev/null and b/models/tankgun_old/tankgun_140mm.dx90.vtx differ
diff --git a/models/tankgun_old/tankgun_140mm.mdl b/models/tankgun_old/tankgun_140mm.mdl
new file mode 100644
index 000000000..cf820f847
Binary files /dev/null and b/models/tankgun_old/tankgun_140mm.mdl differ
diff --git a/models/tankgun_old/tankgun_140mm.phy b/models/tankgun_old/tankgun_140mm.phy
new file mode 100644
index 000000000..a6467bca1
Binary files /dev/null and b/models/tankgun_old/tankgun_140mm.phy differ
diff --git a/models/tankgun_old/tankgun_140mm.sw.vtx b/models/tankgun_old/tankgun_140mm.sw.vtx
new file mode 100644
index 000000000..c63310931
Binary files /dev/null and b/models/tankgun_old/tankgun_140mm.sw.vtx differ
diff --git a/models/tankgun_old/tankgun_140mm.vvd b/models/tankgun_old/tankgun_140mm.vvd
new file mode 100644
index 000000000..b6ed6e02c
Binary files /dev/null and b/models/tankgun_old/tankgun_140mm.vvd differ
diff --git a/models/tankgun_old/tankgun_50mm.dx80.vtx b/models/tankgun_old/tankgun_50mm.dx80.vtx
new file mode 100644
index 000000000..abbe089a2
Binary files /dev/null and b/models/tankgun_old/tankgun_50mm.dx80.vtx differ
diff --git a/models/tankgun_old/tankgun_50mm.dx90.vtx b/models/tankgun_old/tankgun_50mm.dx90.vtx
new file mode 100644
index 000000000..612ebd8e6
Binary files /dev/null and b/models/tankgun_old/tankgun_50mm.dx90.vtx differ
diff --git a/models/tankgun_old/tankgun_50mm.mdl b/models/tankgun_old/tankgun_50mm.mdl
new file mode 100644
index 000000000..240bf411d
Binary files /dev/null and b/models/tankgun_old/tankgun_50mm.mdl differ
diff --git a/models/tankgun_old/tankgun_50mm.phy b/models/tankgun_old/tankgun_50mm.phy
new file mode 100644
index 000000000..fc67b55ba
Binary files /dev/null and b/models/tankgun_old/tankgun_50mm.phy differ
diff --git a/models/tankgun_old/tankgun_50mm.sw.vtx b/models/tankgun_old/tankgun_50mm.sw.vtx
new file mode 100644
index 000000000..5d584ae07
Binary files /dev/null and b/models/tankgun_old/tankgun_50mm.sw.vtx differ
diff --git a/models/tankgun_old/tankgun_50mm.vvd b/models/tankgun_old/tankgun_50mm.vvd
new file mode 100644
index 000000000..c798d7d9f
Binary files /dev/null and b/models/tankgun_old/tankgun_50mm.vvd differ
diff --git a/models/tankgun_old/tankgun_75mm.dx80.vtx b/models/tankgun_old/tankgun_75mm.dx80.vtx
new file mode 100644
index 000000000..e80b2a87c
Binary files /dev/null and b/models/tankgun_old/tankgun_75mm.dx80.vtx differ
diff --git a/models/tankgun_old/tankgun_75mm.dx90.vtx b/models/tankgun_old/tankgun_75mm.dx90.vtx
new file mode 100644
index 000000000..e4c1e3270
Binary files /dev/null and b/models/tankgun_old/tankgun_75mm.dx90.vtx differ
diff --git a/models/tankgun_old/tankgun_75mm.mdl b/models/tankgun_old/tankgun_75mm.mdl
new file mode 100644
index 000000000..4c19ac6db
Binary files /dev/null and b/models/tankgun_old/tankgun_75mm.mdl differ
diff --git a/models/tankgun_old/tankgun_75mm.phy b/models/tankgun_old/tankgun_75mm.phy
new file mode 100644
index 000000000..072431386
Binary files /dev/null and b/models/tankgun_old/tankgun_75mm.phy differ
diff --git a/models/tankgun_old/tankgun_75mm.sw.vtx b/models/tankgun_old/tankgun_75mm.sw.vtx
new file mode 100644
index 000000000..4f0431120
Binary files /dev/null and b/models/tankgun_old/tankgun_75mm.sw.vtx differ
diff --git a/models/tankgun_old/tankgun_75mm.vvd b/models/tankgun_old/tankgun_75mm.vvd
new file mode 100644
index 000000000..0bc935e31
Binary files /dev/null and b/models/tankgun_old/tankgun_75mm.vvd differ
diff --git a/models/Vehicles/driver_pod.dx80.vtx b/models/vehicles/driver_pod.dx80.vtx
similarity index 100%
rename from models/Vehicles/driver_pod.dx80.vtx
rename to models/vehicles/driver_pod.dx80.vtx
diff --git a/models/Vehicles/driver_pod.dx90.vtx b/models/vehicles/driver_pod.dx90.vtx
similarity index 100%
rename from models/Vehicles/driver_pod.dx90.vtx
rename to models/vehicles/driver_pod.dx90.vtx
diff --git a/models/Vehicles/driver_pod.mdl b/models/vehicles/driver_pod.mdl
similarity index 100%
rename from models/Vehicles/driver_pod.mdl
rename to models/vehicles/driver_pod.mdl
diff --git a/models/Vehicles/driver_pod.phy b/models/vehicles/driver_pod.phy
similarity index 100%
rename from models/Vehicles/driver_pod.phy
rename to models/vehicles/driver_pod.phy
diff --git a/models/Vehicles/driver_pod.sw.vtx b/models/vehicles/driver_pod.sw.vtx
similarity index 100%
rename from models/Vehicles/driver_pod.sw.vtx
rename to models/vehicles/driver_pod.sw.vtx
diff --git a/models/Vehicles/driver_pod.vvd b/models/vehicles/driver_pod.vvd
similarity index 100%
rename from models/Vehicles/driver_pod.vvd
rename to models/vehicles/driver_pod.vvd
diff --git a/models/Vehicles/pilot_seat.dx80.vtx b/models/vehicles/pilot_seat.dx80.vtx
similarity index 100%
rename from models/Vehicles/pilot_seat.dx80.vtx
rename to models/vehicles/pilot_seat.dx80.vtx
diff --git a/models/Vehicles/pilot_seat.dx90.vtx b/models/vehicles/pilot_seat.dx90.vtx
similarity index 100%
rename from models/Vehicles/pilot_seat.dx90.vtx
rename to models/vehicles/pilot_seat.dx90.vtx
diff --git a/models/Vehicles/pilot_seat.mdl b/models/vehicles/pilot_seat.mdl
similarity index 100%
rename from models/Vehicles/pilot_seat.mdl
rename to models/vehicles/pilot_seat.mdl
diff --git a/models/Vehicles/pilot_seat.phy b/models/vehicles/pilot_seat.phy
similarity index 100%
rename from models/Vehicles/pilot_seat.phy
rename to models/vehicles/pilot_seat.phy
diff --git a/models/Vehicles/pilot_seat.sw.vtx b/models/vehicles/pilot_seat.sw.vtx
similarity index 100%
rename from models/Vehicles/pilot_seat.sw.vtx
rename to models/vehicles/pilot_seat.sw.vtx
diff --git a/models/Vehicles/pilot_seat.vvd b/models/vehicles/pilot_seat.vvd
similarity index 100%
rename from models/Vehicles/pilot_seat.vvd
rename to models/vehicles/pilot_seat.vvd
diff --git a/models/weapons/W_cuttingtorch.dx80.vtx b/models/weapons/w_cuttingtorch.dx80.vtx
similarity index 100%
rename from models/weapons/W_cuttingtorch.dx80.vtx
rename to models/weapons/w_cuttingtorch.dx80.vtx
diff --git a/models/weapons/W_cuttingtorch.dx90.vtx b/models/weapons/w_cuttingtorch.dx90.vtx
similarity index 100%
rename from models/weapons/W_cuttingtorch.dx90.vtx
rename to models/weapons/w_cuttingtorch.dx90.vtx
diff --git a/models/weapons/W_cuttingtorch.phy b/models/weapons/w_cuttingtorch.phy
similarity index 100%
rename from models/weapons/W_cuttingtorch.phy
rename to models/weapons/w_cuttingtorch.phy
diff --git a/models/weapons/W_cuttingtorch.sw.vtx b/models/weapons/w_cuttingtorch.sw.vtx
similarity index 100%
rename from models/weapons/W_cuttingtorch.sw.vtx
rename to models/weapons/w_cuttingtorch.sw.vtx
diff --git a/particles/acf_muzzleflashes.pcf b/particles/acf_muzzleflashes.pcf
index 966d7e2c1..5718e64d4 100644
Binary files a/particles/acf_muzzleflashes.pcf and b/particles/acf_muzzleflashes.pcf differ
diff --git a/particles/muzzleflashes.txt b/particles/muzzleflashes.txt
deleted file mode 100644
index b2e17c966..000000000
--- a/particles/muzzleflashes.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Effect names:
-
-50cal_muzzleflash_noscale
-30mm_muzzleflash_noscale
-40mm_muzzleflash_noscale
-120mm_muzzleflash_noscale
-155mm_muzzleflash_noscale
-6pder_muzzleflash_noscale
diff --git a/particles/particles_manifest.txt b/particles/particles_manifest.txt
deleted file mode 100644
index eab448f3c..000000000
--- a/particles/particles_manifest.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-particles_manifest
-{
- "file" "particles/rocket_motor.pcf"
- "file" "particles/acf_muzzleflashes.pcf"
-
-}
diff --git a/particles/rocket_motor.pcf b/particles/rocket_motor.pcf
index 513ba150d..203bf2174 100644
Binary files a/particles/rocket_motor.pcf and b/particles/rocket_motor.pcf differ
diff --git a/readme.txt b/readme.txt
new file mode 100644
index 000000000..266fb20df
--- /dev/null
+++ b/readme.txt
@@ -0,0 +1,170 @@
+------------------
+-- INSTALLATION --
+------------------
+
+- Recommended installation: SVN
+ If you don't have a svn program, TortoiseSVN is a good one. http://TortoiseSVN.net
+ This walkthrough assumes you are using TortoiseSVN, and have it installed already.
+
+ Go to your garrysmod addons folder ( \SteamApps\common\GarrysMod\garrysmod\addons ), create a new
+ folder named ACF, right click it and choose "SVN Checkout". In the "URL of repository" box, put
+ "https://github.com/nrlulz/ACF/trunk" (without the "") and click OK. ACF is a fairly large addon,
+ so it will take some time to download.
+
+ If you want to update the ACF SVN at some point, right click the ACF folder in your addons and choose
+ "SVN Update".
+
+- Last resort installation
+ If you're having problems with SVN, you can download a zip file directly from github. However, this
+ is NOT RECOMMENDED as it's a large, slow download, has a LOT of extra unused stuff which bloats the zip,
+ and you have to redownload the entire thing if you want to update ACF.
+
+ Go to https://github.com/nrlulz/ACF and click the "Download Zip" button on the right side of the page.
+ If you don't have an ACF folder inside your addons, create one. Open the zip, go into the "ACF-Master"
+ folder, and extract all the files into your ACF folder in addons. The folder structure should look
+ like "garrysmod\addons\ACF\lua" and NOT "garrysmod\addons\ACF\ACF-Master\lua".
+
+- If you are updating a previous installation of ACF and you're having issues with
+ vanilla particles (fire, blood) not showing up, delete your garrysmod/particles/
+ directory.
+
+- It is not necessary to copy the scripts or particles directories anymore.
+
+- IF YOU ARE HAVING INSTALLATION PROBLEMS, PLEASE POST ON THE FACEPUNCH ACF THREAD, NOT ON GITHUB.
+ Please only create an issue on github if you've found a bug, or have a suggestion. The FP forum thread
+ is a good place for general ACF conversation, suggestions, and help requests.
+ Forum thread: https://facepunch.com/showthread.php?t=1548397
+
+- If you're into ACF combat, Knight Icy has an excellent extra sound pack for weapons on the GMod workshop.
+ Check it out at http://steamcommunity.com/sharedfiles/filedetails/?id=301482990
+
+
+---------------------------------------------------------------
+-- IF YOU WANT ACF POWERED STUFF TO GO MORE REALISTIC SPEEDS --
+---------------------------------------------------------------
+
+Put these two lines in your server.cfg:
+
+lua_run local tbl = physenv.GetPerformanceSettings() tbl.MaxAngularVelocity = 30000 physenv.SetPerformanceSettings(tbl)
+lua_run local tbl = physenv.GetPerformanceSettings() tbl.MaxVelocity = 20000 physenv.SetPerformanceSettings(tbl)
+
+This will raise the angular velocity limit (wheels spinning) and forward speed limit.
+
+
+--------------------
+-- FOR DEVELOPERS --
+--------------------
+
+Frankess has added some handy hooks that can be used to limit damage and explosions
+and such. They are as follows:
+
+ACF_BulletsFlight( Index, Bullet )
+ Return false to skip checking if the bullet hit something
+ Args:
+ - Index (number): the bullet's index
+ - Bullet (BulletData): the bullet object
+
+ACF_BulletDamage( Type, Entity, Energy, Area, Angle, Inflictor, Bone, Gun, IsFromAmmo )
+ Return false to prevent damage
+ Args:
+ - Type (string): the ACF entity type (prop/vehicle/squishy)
+ - Entity (entity): the entity being hit
+ - Energy (table): kinetic energy
+ - Area (number): area in cm^2
+ - Angle (number): angle of bullet to armor
+ - Inflictor (player): owner of bullet
+ - Bone (number): the bone being hit
+ - Gun (entity): the gun that fired the bullet
+ - IsFromAmmo (boolean): true if this is from an ammo explosion (don't think this is implemented yet)
+
+ACF_KEShove( Target, Pos, Dir, KE )
+ Return false to prevent kinetic shove
+ Args:
+ - Target (entity): the entity being shoved
+ - Pos (vector): the position the shove is applied from
+ - Dir (vector): the direction of the shove
+ - KE (number): force of the shove in KJ
+
+ACF_FireShell( Gun, Bullet )
+ Return false to prevent gun from firing
+ Args:
+ - Gun (entity): the gun in question
+ - Bullet (BulletData): the bullet that would be fired
+
+ACF_AmmoExplode( Ammo, Bullet )
+ Return false to prevent ammo crate from exploding
+ Args:
+ - Ammo (entity): the ammo crate in question
+ - Bullet (BulletData): the bullet that would be fired
+
+ACF_FuelExplode( Tank )
+ Return false to prevent fuel tank from exploding
+ Args:
+ - Tank (entity): the fuel tank in question
+
+ACF_CanRefill( Refill, Ammo )
+ Return false to prevent ammo crate from being refilled (not yet implemented)
+
+
+
+------------------------
+Damage Protection hooks:
+
+ACF_PlayerChangedZone
+ This hook is called whenever a player moves between the battlefield and a safezone, or between safezones.
+ This hook is called regardless of damage protection mode e.g. during build mode where safezones are irrelevant.
+Args;
+ ply Player: The player who has just transitioned from one zone to another.
+ zone String: The name of the zone which the player has moved into (or nil if moved into battlefield)
+ oldzone String: The name of the zone which the player has exited (or nil if exited battlefield)
+
+
+ACF_ProtectionModeChanged
+ This hook is called whenever the damage protection mode is altered.
+ This hook is also called once at startup, when the damage protection mode is initialized to "default" (oldmode = nil during this run).
+Args;
+ mode String: The name of the newly activated damage protection mode.
+ oldmode String: The name of the damage protection mode which has just been deactivated.
+
+
+
+-----------------------
+Bullet table callbacks:
+
+For the argument list (Index, Bullet, FlightRes):
+ Index: Index of the bullet in the bullet-list.
+ Bullet: The bullet data table.
+ FlightRes: The results of the bullet trace.
+- - - - - -
+
+OnEndFlight(Index, Bullet, FlightRes)
+ called when a bullet ends its flight (explodes etc)
+
+OnPenetrated(Index, Bullet, FlightRes)
+ when a bullet pierces the world or an entity
+
+OnRicochet(Index, Bullet, FlightRes)
+ when a bullet bounces off an entity
+
+PreCalcFlight(Bullet)
+ just before the bullet performs a flight step
+
+PostCalcFlight(Bullet)
+ just after the bullet performs a flight step
+
+HandlesOwnIteration
+ this is just a key: put it into the bullet table to prevent ACF from iterating the bullet. You can then iterate it yourself in different places.
+
+
+---------------------
+Engine model scaling:
+
+V engines
+Large 1.0
+Medium 0.665
+Small 0.532
+
+Inline engines
+Large 1.0
+Medium 0.6
+Small 0.4
diff --git a/scripts/sounds/engines_acf.txt b/scripts/sounds/engines_acf.txt
deleted file mode 100644
index 24ff03b0f..000000000
--- a/scripts/sounds/engines_acf.txt
+++ /dev/null
@@ -1,317 +0,0 @@
-
-// Rednecks
-"V8.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/v8_petrolsmall.wav"
-}
-"V8.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/v8_petrolmedium.wav"
-}
-"V8.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/v8_petrollarge.wav"
-}
-
-
-//Rednecks diesel
-
-
-"V8D.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/v8_dieselsmall.wav"
-}
-"V8D.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/v8_dieselmedium2.wav"
-}
-"V8D.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/v8_diesellarge.wav"
-}
-
-
-
-// 4bangers
-
-"I4D.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/i4_diesel2.wav"
-}
-"I4D.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/i4_dieselmedium.wav"
-}
-"I4D.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/i4_diesellarge.wav"
-}
-
-"I4P.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/i4_petrolsmall2.wav"
-}
-"I4P.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/i4_petrolmedium2.wav"
-}
-"I4P.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/i4_petrollarge.wav"
-}
-
-"L6D.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/l6_dieselsmall.wav"
-}
-"L6D.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/l6_dieselmedium4.wav"
-}
-"L6D.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/l6_diesellarge2.wav"
-}
-
-"L6P.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/l6_petrolsmall2.wav"
-}
-"L6P.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/l6_petrolmedium.wav"
-}
-"L6P.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/l6_petrollarge2.wav"
-}
-
-
-
-
-
-
-
-
-
-
-"V12D.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/v12_dieselsmall.wav"
-}
-"V12D.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/v12_dieselmedium.wav"
-}
-"V12D.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/v12_diesellarge.wav"
-}
-
-"V12P.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/v12_petrolsmall.wav"
-}
-"V12P.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/v12_petrolmedium.wav"
-}
-"V12P.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/v12_petrollarge.wav"
-}
-
-
-// Radials
-"R7.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90DB"
- "wave" "^ACF_engines/R7_petrolsmall.wav"
-}
-"R7.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/R7_petrolmedium.wav"
-}
-"R7.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/R7_petrollarge.wav"
-}
-
-// Turbines
-"GT.Small"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/turbine_small.wav"
-}
-"GT.Medium"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/turbine_medium.wav"
-}
-"GT.Large"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_120DB"
- "wave" "^ACF_engines/turbine_large.wav"
-}
-
-
-"I4P161.Norm"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/i4_petrol16_1.wav"
-}
-
-"I4P162.Norm"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/i4_petrol16_2.wav"
-}
-
-"I4P201.Norm"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/i4_petrol20_1.wav"
-}
-
-
-"I4P202.Norm"
-{
- "channel" "CHAN_STATIC"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_100DB"
- "wave" "^ACF_engines/i4_petrol20_2.wav"
-}
-
-
-
-
-
-
-
-
diff --git a/scripts/sounds/weapon_acf.txt b/scripts/sounds/weapon_acf.txt
deleted file mode 100644
index c81364348..000000000
--- a/scripts/sounds/weapon_acf.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-"Cannon.Fire"
-{
- "channel" "CHAN_WEAPON"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_155DB"
- "wave" "^weapons/ACF_Gun/distancecannon.wav"
-}
-"Autoloader.Fire"
-{
- "channel" "CHAN_WEAPON"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_155DB"
- "wave" "^weapons/ACF_Gun/autoloader.wav"
-}
-
-"Howitzer.Fire"
-{
- "channel" "CHAN_WEAPON"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_155DB"
- "wave" "^weapons/ACF_Gun/distancehowitzer.wav"
-}
-
-"Mortar.Fire"
-{
- "channel" "CHAN_WEAPON"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_155dB"
- "wave" "^weapons/ACF_Gun/distancemortar.wav"
-}
-
-"Autocannon.Fire"
-{
- "channel" "CHAN_WEAPON"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90dB"
- "wave" "^weapons/ACF_Gun/AC_fire3.wav"
-}
-
-"Rotary_Autocannon.Fire"
-{
- "channel" "CHAN_WEAPON"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90dB"
- "wave" "^weapons/ACF_Gun/rac_fire1.wav"
-}
-"Machinegun.Fire"
-{
- "channel" "CHAN_WEAPON"
- "volume" "1.0"
- "pitch" "PITCH_NORM"
- "soundlevel" "SNDLVL_90dB"
- "wave" "^weapons/ACF_Gun/mg_fire1.wav"
-}
-
diff --git a/sound/acf_engines/I4_petrollarge.wav b/sound/acf_engines/I4_petrollarge.wav
deleted file mode 100644
index cfe965284..000000000
Binary files a/sound/acf_engines/I4_petrollarge.wav and /dev/null differ
diff --git a/sound/acf_engines/b4_petrolsmall.wav b/sound/acf_engines/b4_petrolsmall.wav
index 20fad5ea8..3fa14fa9f 100644
Binary files a/sound/acf_engines/b4_petrolsmall.wav and b/sound/acf_engines/b4_petrolsmall.wav differ
diff --git a/sound/acf_engines/b6_petrollarge.WAV b/sound/acf_engines/b6_petrollarge.wav
similarity index 100%
rename from sound/acf_engines/b6_petrollarge.WAV
rename to sound/acf_engines/b6_petrollarge.wav
diff --git a/sound/acf_engines/b6_petrolsmall.WAV b/sound/acf_engines/b6_petrolsmall.wav
similarity index 100%
rename from sound/acf_engines/b6_petrolsmall.WAV
rename to sound/acf_engines/b6_petrolsmall.wav
diff --git a/sound/acf_engines/gwv1716.tmp b/sound/acf_engines/gwv1716.tmp
new file mode 100644
index 000000000..a152604b6
Binary files /dev/null and b/sound/acf_engines/gwv1716.tmp differ
diff --git a/sound/acf_engines/gwv2593.tmp b/sound/acf_engines/gwv2593.tmp
new file mode 100644
index 000000000..70ed9a366
Binary files /dev/null and b/sound/acf_engines/gwv2593.tmp differ
diff --git a/sound/acf_engines/I4_diesel.wav b/sound/acf_engines/i4_diesel.wav
similarity index 100%
rename from sound/acf_engines/I4_diesel.wav
rename to sound/acf_engines/i4_diesel.wav
diff --git a/sound/acf_engines/i4_petrollarge.wav b/sound/acf_engines/i4_petrollarge.wav
new file mode 100644
index 000000000..c9436e3f3
Binary files /dev/null and b/sound/acf_engines/i4_petrollarge.wav differ
diff --git a/sound/acf_engines/I4_petrolmedium.wav b/sound/acf_engines/i4_petrolmedium.wav
similarity index 100%
rename from sound/acf_engines/I4_petrolmedium.wav
rename to sound/acf_engines/i4_petrolmedium.wav
diff --git a/sound/acf_engines/I4_petrolsmall.wav b/sound/acf_engines/i4_petrolsmall.wav
similarity index 100%
rename from sound/acf_engines/I4_petrolsmall.wav
rename to sound/acf_engines/i4_petrolsmall.wav
diff --git a/sound/acf_engines/i4_petrolsmall2.wav b/sound/acf_engines/i4_petrolsmall2.wav
index 8503bb64b..d9cf5a813 100644
Binary files a/sound/acf_engines/i4_petrolsmall2.wav and b/sound/acf_engines/i4_petrolsmall2.wav differ
diff --git a/sound/acf_engines/i4_special.wav b/sound/acf_engines/i4_special.wav
new file mode 100644
index 000000000..40776ae4a
Binary files /dev/null and b/sound/acf_engines/i4_special.wav differ
diff --git a/sound/acf_engines/i5_dieselmedium.wav b/sound/acf_engines/i5_dieselmedium.wav
new file mode 100644
index 000000000..75508e76c
Binary files /dev/null and b/sound/acf_engines/i5_dieselmedium.wav differ
diff --git a/sound/acf_engines/i5_dieselsmall.wav b/sound/acf_engines/i5_dieselsmall.wav
new file mode 100644
index 000000000..2fc96719a
Binary files /dev/null and b/sound/acf_engines/i5_dieselsmall.wav differ
diff --git a/sound/acf_engines/i5_dieselsmall2.wav b/sound/acf_engines/i5_dieselsmall2.wav
new file mode 100644
index 000000000..bcc462a41
Binary files /dev/null and b/sound/acf_engines/i5_dieselsmall2.wav differ
diff --git a/sound/acf_engines/i5_petrolmedium.wav b/sound/acf_engines/i5_petrolmedium.wav
new file mode 100644
index 000000000..9c7fb056c
Binary files /dev/null and b/sound/acf_engines/i5_petrolmedium.wav differ
diff --git a/sound/acf_engines/i5_petrolsmall.wav b/sound/acf_engines/i5_petrolsmall.wav
new file mode 100644
index 000000000..b7477166f
Binary files /dev/null and b/sound/acf_engines/i5_petrolsmall.wav differ
diff --git a/sound/acf_engines/l6_diesellarge2.wav b/sound/acf_engines/l6_diesellarge2.wav
index 8873e5197..5d0586fee 100644
Binary files a/sound/acf_engines/l6_diesellarge2.wav and b/sound/acf_engines/l6_diesellarge2.wav differ
diff --git a/sound/acf_engines/l6_dieselmedium4.wav b/sound/acf_engines/l6_dieselmedium4.wav
index 71966422c..f8f44aaf8 100644
Binary files a/sound/acf_engines/l6_dieselmedium4.wav and b/sound/acf_engines/l6_dieselmedium4.wav differ
diff --git a/sound/acf_engines/l6_dieselsmall.wav b/sound/acf_engines/l6_dieselsmall.wav
index a49141a39..220216906 100644
Binary files a/sound/acf_engines/l6_dieselsmall.wav and b/sound/acf_engines/l6_dieselsmall.wav differ
diff --git a/sound/acf_engines/l6_petrolmedium.wav b/sound/acf_engines/l6_petrolmedium.wav
index a5380cb07..b15d7beb5 100644
Binary files a/sound/acf_engines/l6_petrolmedium.wav and b/sound/acf_engines/l6_petrolmedium.wav differ
diff --git a/sound/acf_engines/l6_petrolsmall2.wav b/sound/acf_engines/l6_petrolsmall2.wav
index cb4c3d855..a5380cb07 100644
Binary files a/sound/acf_engines/l6_petrolsmall2.wav and b/sound/acf_engines/l6_petrolsmall2.wav differ
diff --git a/sound/acf_engines/l6_special.wav b/sound/acf_engines/l6_special.wav
new file mode 100644
index 000000000..556fc8bef
Binary files /dev/null and b/sound/acf_engines/l6_special.wav differ
diff --git a/sound/acf_engines/mid_on_in.wav b/sound/acf_engines/mid_on_in.wav
new file mode 100644
index 000000000..7836546b1
Binary files /dev/null and b/sound/acf_engines/mid_on_in.wav differ
diff --git a/sound/acf_engines/newl6pet.wav b/sound/acf_engines/newl6pet.wav
new file mode 100644
index 000000000..5ae0333f6
Binary files /dev/null and b/sound/acf_engines/newl6pet.wav differ
diff --git a/sound/acf_engines/r7_petrollarge.wav b/sound/acf_engines/r7_petrollarge.wav
index 9f14d12fc..ec61a9c75 100644
Binary files a/sound/acf_engines/r7_petrollarge.wav and b/sound/acf_engines/r7_petrollarge.wav differ
diff --git a/sound/acf_engines/r7_petrolmedium.wav b/sound/acf_engines/r7_petrolmedium.wav
index 221770570..f69080ab7 100644
Binary files a/sound/acf_engines/r7_petrolmedium.wav and b/sound/acf_engines/r7_petrolmedium.wav differ
diff --git a/sound/acf_engines/v10_diesellarge.wav b/sound/acf_engines/v10_diesellarge.wav
new file mode 100644
index 000000000..09eeeb650
Binary files /dev/null and b/sound/acf_engines/v10_diesellarge.wav differ
diff --git a/sound/acf_engines/v10_petrolmedium.wav b/sound/acf_engines/v10_petrolmedium.wav
new file mode 100644
index 000000000..ca67abbb0
Binary files /dev/null and b/sound/acf_engines/v10_petrolmedium.wav differ
diff --git a/sound/acf_engines/v10_petrolsmall.wav b/sound/acf_engines/v10_petrolsmall.wav
new file mode 100644
index 000000000..c4b21f7c7
Binary files /dev/null and b/sound/acf_engines/v10_petrolsmall.wav differ
diff --git a/sound/acf_engines/v10_special.wav b/sound/acf_engines/v10_special.wav
new file mode 100644
index 000000000..5a252e7b5
Binary files /dev/null and b/sound/acf_engines/v10_special.wav differ
diff --git a/sound/acf_engines/v12_dieselmedium.wav b/sound/acf_engines/v12_dieselmedium.wav
index 00ffebd19..91040783c 100644
Binary files a/sound/acf_engines/v12_dieselmedium.wav and b/sound/acf_engines/v12_dieselmedium.wav differ
diff --git a/sound/acf_engines/v12_petrollarge.wav b/sound/acf_engines/v12_petrollarge.wav
index 765292276..fa2860396 100644
Binary files a/sound/acf_engines/v12_petrollarge.wav and b/sound/acf_engines/v12_petrollarge.wav differ
diff --git a/sound/acf_engines/v12_petrollargeorig.wav b/sound/acf_engines/v12_petrollargeorig.wav
new file mode 100644
index 000000000..086c7be71
Binary files /dev/null and b/sound/acf_engines/v12_petrollargeorig.wav differ
diff --git a/sound/acf_engines/v12_special.wav b/sound/acf_engines/v12_special.wav
new file mode 100644
index 000000000..ba8fe1990
Binary files /dev/null and b/sound/acf_engines/v12_special.wav differ
diff --git a/sound/acf_engines/v6_diesellarge.wav b/sound/acf_engines/v6_diesellarge.wav
new file mode 100644
index 000000000..05e7800a0
Binary files /dev/null and b/sound/acf_engines/v6_diesellarge.wav differ
diff --git a/sound/acf_engines/v6_petrolmedium.wav b/sound/acf_engines/v6_petrolmedium.wav
index 37518d29a..0cffad1c5 100644
Binary files a/sound/acf_engines/v6_petrolmedium.wav and b/sound/acf_engines/v6_petrolmedium.wav differ
diff --git a/sound/acf_engines/v6_petrolsmall.wav b/sound/acf_engines/v6_petrolsmall.wav
index 1814d8a1a..e0349653a 100644
Binary files a/sound/acf_engines/v6_petrolsmall.wav and b/sound/acf_engines/v6_petrolsmall.wav differ
diff --git a/sound/acf_engines/v8_dieselmedium2.wav b/sound/acf_engines/v8_dieselmedium2.wav
index b481a0d5a..ba4d3b93b 100644
Binary files a/sound/acf_engines/v8_dieselmedium2.wav and b/sound/acf_engines/v8_dieselmedium2.wav differ
diff --git a/sound/acf_engines/v8_petrollarge.wav b/sound/acf_engines/v8_petrollarge.wav
index 43c93512a..a28cc8b7c 100644
Binary files a/sound/acf_engines/v8_petrollarge.wav and b/sound/acf_engines/v8_petrollarge.wav differ
diff --git a/sound/acf_engines/v8_petrolmedium.wav b/sound/acf_engines/v8_petrolmedium.wav
index d7c9e968f..1a7599da4 100644
Binary files a/sound/acf_engines/v8_petrolmedium.wav and b/sound/acf_engines/v8_petrolmedium.wav differ
diff --git a/sound/acf_engines/v8_special.wav b/sound/acf_engines/v8_special.wav
new file mode 100644
index 000000000..d36ef1260
Binary files /dev/null and b/sound/acf_engines/v8_special.wav differ
diff --git a/sound/acf_engines/v8_special2.wav b/sound/acf_engines/v8_special2.wav
new file mode 100644
index 000000000..5ef8dadba
Binary files /dev/null and b/sound/acf_engines/v8_special2.wav differ
diff --git a/sound/acf_engines/wankel_large.wav b/sound/acf_engines/wankel_large.wav
new file mode 100644
index 000000000..be8f9327a
Binary files /dev/null and b/sound/acf_engines/wankel_large.wav differ
diff --git a/sound/acf_engines/wankel_medium.wav b/sound/acf_engines/wankel_medium.wav
new file mode 100644
index 000000000..edb7a67b6
Binary files /dev/null and b/sound/acf_engines/wankel_medium.wav differ
diff --git a/sound/acf_engines/wankel_small.wav b/sound/acf_engines/wankel_small.wav
new file mode 100644
index 000000000..97547b4cf
Binary files /dev/null and b/sound/acf_engines/wankel_small.wav differ
diff --git a/sound/acf_extra/STEAMTRN.wav b/sound/acf_extra/STEAMTRN.wav
new file mode 100644
index 000000000..cefb4650e
Binary files /dev/null and b/sound/acf_extra/STEAMTRN.wav differ
diff --git a/sound/acf_extra/airfx/F22_hydroalarm.wav b/sound/acf_extra/airfx/F22_hydroalarm.wav
new file mode 100644
index 000000000..587ae7edf
Binary files /dev/null and b/sound/acf_extra/airfx/F22_hydroalarm.wav differ
diff --git a/sound/acf_extra/airfx/FW1901.wav b/sound/acf_extra/airfx/FW1901.wav
new file mode 100644
index 000000000..83afcaeac
Binary files /dev/null and b/sound/acf_extra/airfx/FW1901.wav differ
diff --git a/sound/acf_extra/airfx/FW1902.wav b/sound/acf_extra/airfx/FW1902.wav
new file mode 100644
index 000000000..a648d0954
Binary files /dev/null and b/sound/acf_extra/airfx/FW1902.wav differ
diff --git a/sound/acf_extra/airfx/FX_flyby01.wav b/sound/acf_extra/airfx/FX_flyby01.wav
new file mode 100644
index 000000000..d72a72f0c
Binary files /dev/null and b/sound/acf_extra/airfx/FX_flyby01.wav differ
diff --git a/sound/acf_extra/airfx/Hurricane1.wav b/sound/acf_extra/airfx/Hurricane1.wav
new file mode 100644
index 000000000..fa9cf0b1e
Binary files /dev/null and b/sound/acf_extra/airfx/Hurricane1.wav differ
diff --git a/sound/acf_extra/airfx/Hurricane2.wav b/sound/acf_extra/airfx/Hurricane2.wav
new file mode 100644
index 000000000..ce3c4e7ac
Binary files /dev/null and b/sound/acf_extra/airfx/Hurricane2.wav differ
diff --git a/sound/acf_extra/airfx/P47D.wav b/sound/acf_extra/airfx/P47D.wav
new file mode 100644
index 000000000..8171a4ff7
Binary files /dev/null and b/sound/acf_extra/airfx/P47D.wav differ
diff --git a/sound/acf_extra/airfx/Spitfire.wav b/sound/acf_extra/airfx/Spitfire.wav
new file mode 100644
index 000000000..c5078015e
Binary files /dev/null and b/sound/acf_extra/airfx/Spitfire.wav differ
diff --git a/sound/acf_extra/airfx/Storch.wav b/sound/acf_extra/airfx/Storch.wav
new file mode 100644
index 000000000..b5127031e
Binary files /dev/null and b/sound/acf_extra/airfx/Storch.wav differ
diff --git a/sound/acf_extra/airfx/Stuka.wav b/sound/acf_extra/airfx/Stuka.wav
new file mode 100644
index 000000000..22e684b60
Binary files /dev/null and b/sound/acf_extra/airfx/Stuka.wav differ
diff --git a/sound/acf_extra/airfx/TOW_reload.wav b/sound/acf_extra/airfx/TOW_reload.wav
new file mode 100644
index 000000000..68a9e0fcb
Binary files /dev/null and b/sound/acf_extra/airfx/TOW_reload.wav differ
diff --git a/sound/acf_extra/airfx/afterburner.wav b/sound/acf_extra/airfx/afterburner.wav
new file mode 100644
index 000000000..d4baa8aa9
Binary files /dev/null and b/sound/acf_extra/airfx/afterburner.wav differ
diff --git a/sound/acf_extra/airfx/air_distant.wav b/sound/acf_extra/airfx/air_distant.wav
new file mode 100644
index 000000000..6e36121ad
Binary files /dev/null and b/sound/acf_extra/airfx/air_distant.wav differ
diff --git a/sound/acf_extra/airfx/aircraft_jet_a10_loop_1.wav b/sound/acf_extra/airfx/aircraft_jet_a10_loop_1.wav
new file mode 100644
index 000000000..39075793f
Binary files /dev/null and b/sound/acf_extra/airfx/aircraft_jet_a10_loop_1.wav differ
diff --git a/sound/acf_extra/airfx/apache_loop.wav b/sound/acf_extra/airfx/apache_loop.wav
new file mode 100644
index 000000000..f0307bc15
Binary files /dev/null and b/sound/acf_extra/airfx/apache_loop.wav differ
diff --git a/sound/acf_extra/airfx/beaufighter (2).wav b/sound/acf_extra/airfx/beaufighter (2).wav
new file mode 100644
index 000000000..c7b5bdd76
Binary files /dev/null and b/sound/acf_extra/airfx/beaufighter (2).wav differ
diff --git a/sound/acf_extra/airfx/beaufighter.wav b/sound/acf_extra/airfx/beaufighter.wav
new file mode 100644
index 000000000..28a97d23c
Binary files /dev/null and b/sound/acf_extra/airfx/beaufighter.wav differ
diff --git a/sound/acf_extra/airfx/bf109 (2).wav b/sound/acf_extra/airfx/bf109 (2).wav
new file mode 100644
index 000000000..84a3c8b2c
Binary files /dev/null and b/sound/acf_extra/airfx/bf109 (2).wav differ
diff --git a/sound/acf_extra/airfx/bf109.wav b/sound/acf_extra/airfx/bf109.wav
new file mode 100644
index 000000000..77e9e0a30
Binary files /dev/null and b/sound/acf_extra/airfx/bf109.wav differ
diff --git a/sound/acf_extra/airfx/bf109_F4.wav b/sound/acf_extra/airfx/bf109_F4.wav
new file mode 100644
index 000000000..02c5ae4f9
Binary files /dev/null and b/sound/acf_extra/airfx/bf109_F4.wav differ
diff --git a/sound/acf_extra/airfx/bf109_f4 (2).wav b/sound/acf_extra/airfx/bf109_f4 (2).wav
new file mode 100644
index 000000000..731b3c7f1
Binary files /dev/null and b/sound/acf_extra/airfx/bf109_f4 (2).wav differ
diff --git a/sound/acf_extra/airfx/blackhawkrotors.wav b/sound/acf_extra/airfx/blackhawkrotors.wav
new file mode 100644
index 000000000..621c65800
Binary files /dev/null and b/sound/acf_extra/airfx/blackhawkrotors.wav differ
diff --git a/sound/acf_extra/airfx/bomb_reload.wav b/sound/acf_extra/airfx/bomb_reload.wav
new file mode 100644
index 000000000..e96c97b32
Binary files /dev/null and b/sound/acf_extra/airfx/bomb_reload.wav differ
diff --git a/sound/acf_extra/airfx/bombbay.wav b/sound/acf_extra/airfx/bombbay.wav
new file mode 100644
index 000000000..704b80ed7
Binary files /dev/null and b/sound/acf_extra/airfx/bombbay.wav differ
diff --git a/sound/acf_extra/airfx/c130_loop.wav b/sound/acf_extra/airfx/c130_loop.wav
new file mode 100644
index 000000000..ac27ca9b7
Binary files /dev/null and b/sound/acf_extra/airfx/c130_loop.wav differ
diff --git a/sound/acf_extra/airfx/c130_rotors.wav b/sound/acf_extra/airfx/c130_rotors.wav
new file mode 100644
index 000000000..23cc33107
Binary files /dev/null and b/sound/acf_extra/airfx/c130_rotors.wav differ
diff --git a/sound/acf_extra/airfx/canopy_close.wav b/sound/acf_extra/airfx/canopy_close.wav
new file mode 100644
index 000000000..30dfb00c8
Binary files /dev/null and b/sound/acf_extra/airfx/canopy_close.wav differ
diff --git a/sound/acf_extra/airfx/canopy_open.wav b/sound/acf_extra/airfx/canopy_open.wav
new file mode 100644
index 000000000..42035b4d1
Binary files /dev/null and b/sound/acf_extra/airfx/canopy_open.wav differ
diff --git a/sound/acf_extra/airfx/caution2.wav b/sound/acf_extra/airfx/caution2.wav
new file mode 100644
index 000000000..8ed848e82
Binary files /dev/null and b/sound/acf_extra/airfx/caution2.wav differ
diff --git a/sound/acf_extra/airfx/cobra.wav b/sound/acf_extra/airfx/cobra.wav
new file mode 100644
index 000000000..48811ff53
Binary files /dev/null and b/sound/acf_extra/airfx/cobra.wav differ
diff --git a/sound/acf_extra/airfx/cobratorots.wav b/sound/acf_extra/airfx/cobratorots.wav
new file mode 100644
index 000000000..6a3d8709b
Binary files /dev/null and b/sound/acf_extra/airfx/cobratorots.wav differ
diff --git a/sound/acf_extra/airfx/cockpit_heli.wav b/sound/acf_extra/airfx/cockpit_heli.wav
new file mode 100644
index 000000000..38e85ff18
Binary files /dev/null and b/sound/acf_extra/airfx/cockpit_heli.wav differ
diff --git a/sound/acf_extra/airfx/cockpit_heli2.wav b/sound/acf_extra/airfx/cockpit_heli2.wav
new file mode 100644
index 000000000..c7a6d8f18
Binary files /dev/null and b/sound/acf_extra/airfx/cockpit_heli2.wav differ
diff --git a/sound/acf_extra/airfx/cockpit_plane.wav b/sound/acf_extra/airfx/cockpit_plane.wav
new file mode 100644
index 000000000..e9548cd80
Binary files /dev/null and b/sound/acf_extra/airfx/cockpit_plane.wav differ
diff --git a/sound/acf_extra/airfx/cockpit_tone01.wav b/sound/acf_extra/airfx/cockpit_tone01.wav
new file mode 100644
index 000000000..98707d8c9
Binary files /dev/null and b/sound/acf_extra/airfx/cockpit_tone01.wav differ
diff --git a/sound/acf_extra/airfx/cockpit_tone02.wav b/sound/acf_extra/airfx/cockpit_tone02.wav
new file mode 100644
index 000000000..a7f2a932e
Binary files /dev/null and b/sound/acf_extra/airfx/cockpit_tone02.wav differ
diff --git a/sound/acf_extra/airfx/cockpit_tone03.wav b/sound/acf_extra/airfx/cockpit_tone03.wav
new file mode 100644
index 000000000..bf2d9cfe2
Binary files /dev/null and b/sound/acf_extra/airfx/cockpit_tone03.wav differ
diff --git a/sound/acf_extra/airfx/cockpit_tone04.wav b/sound/acf_extra/airfx/cockpit_tone04.wav
new file mode 100644
index 000000000..790ee5b03
Binary files /dev/null and b/sound/acf_extra/airfx/cockpit_tone04.wav differ
diff --git a/sound/acf_extra/airfx/crashalarm.wav b/sound/acf_extra/airfx/crashalarm.wav
new file mode 100644
index 000000000..88b462536
Binary files /dev/null and b/sound/acf_extra/airfx/crashalarm.wav differ
diff --git a/sound/acf_extra/airfx/damagealarm.wav b/sound/acf_extra/airfx/damagealarm.wav
new file mode 100644
index 000000000..05249de5a
Binary files /dev/null and b/sound/acf_extra/airfx/damagealarm.wav differ
diff --git a/sound/acf_extra/airfx/f-15.wav b/sound/acf_extra/airfx/f-15.wav
new file mode 100644
index 000000000..f10ed02ba
Binary files /dev/null and b/sound/acf_extra/airfx/f-15.wav differ
diff --git a/sound/acf_extra/airfx/f-18.wav b/sound/acf_extra/airfx/f-18.wav
new file mode 100644
index 000000000..7a23c5f46
Binary files /dev/null and b/sound/acf_extra/airfx/f-18.wav differ
diff --git a/sound/acf_extra/airfx/fire_alarm.wav b/sound/acf_extra/airfx/fire_alarm.wav
new file mode 100644
index 000000000..1be0a7eef
Binary files /dev/null and b/sound/acf_extra/airfx/fire_alarm.wav differ
diff --git a/sound/acf_extra/airfx/fw190.wav b/sound/acf_extra/airfx/fw190.wav
new file mode 100644
index 000000000..f765b0825
Binary files /dev/null and b/sound/acf_extra/airfx/fw190.wav differ
diff --git a/sound/acf_extra/airfx/gear_down.wav b/sound/acf_extra/airfx/gear_down.wav
new file mode 100644
index 000000000..e19296e52
Binary files /dev/null and b/sound/acf_extra/airfx/gear_down.wav differ
diff --git a/sound/acf_extra/airfx/gear_up.wav b/sound/acf_extra/airfx/gear_up.wav
new file mode 100644
index 000000000..6743ebe68
Binary files /dev/null and b/sound/acf_extra/airfx/gear_up.wav differ
diff --git a/sound/acf_extra/airfx/hairier.wav b/sound/acf_extra/airfx/hairier.wav
new file mode 100644
index 000000000..ba048f7d2
Binary files /dev/null and b/sound/acf_extra/airfx/hairier.wav differ
diff --git a/sound/acf_extra/airfx/havoc.wav b/sound/acf_extra/airfx/havoc.wav
new file mode 100644
index 000000000..c8fecaa69
Binary files /dev/null and b/sound/acf_extra/airfx/havoc.wav differ
diff --git a/sound/acf_extra/airfx/heatseeker_lock.wav b/sound/acf_extra/airfx/heatseeker_lock.wav
new file mode 100644
index 000000000..89d35b403
Binary files /dev/null and b/sound/acf_extra/airfx/heatseeker_lock.wav differ
diff --git a/sound/acf_extra/airfx/heatseeker_warning.wav b/sound/acf_extra/airfx/heatseeker_warning.wav
new file mode 100644
index 000000000..f5b2f1b36
Binary files /dev/null and b/sound/acf_extra/airfx/heatseeker_warning.wav differ
diff --git a/sound/acf_extra/airfx/heli_chinook_loop_1.wav b/sound/acf_extra/airfx/heli_chinook_loop_1.wav
new file mode 100644
index 000000000..b30accb64
Binary files /dev/null and b/sound/acf_extra/airfx/heli_chinook_loop_1.wav differ
diff --git a/sound/acf_extra/airfx/heli_damage_rotor_1.wav b/sound/acf_extra/airfx/heli_damage_rotor_1.wav
new file mode 100644
index 000000000..c20b63c87
Binary files /dev/null and b/sound/acf_extra/airfx/heli_damage_rotor_1.wav differ
diff --git a/sound/acf_extra/airfx/heli_damage_rotor_2.wav b/sound/acf_extra/airfx/heli_damage_rotor_2.wav
new file mode 100644
index 000000000..4427b364f
Binary files /dev/null and b/sound/acf_extra/airfx/heli_damage_rotor_2.wav differ
diff --git a/sound/acf_extra/airfx/heli_damage_tail.wav b/sound/acf_extra/airfx/heli_damage_tail.wav
new file mode 100644
index 000000000..bff62551d
Binary files /dev/null and b/sound/acf_extra/airfx/heli_damage_tail.wav differ
diff --git a/sound/acf_extra/airfx/heliinside1.wav b/sound/acf_extra/airfx/heliinside1.wav
new file mode 100644
index 000000000..8de7c5b6b
Binary files /dev/null and b/sound/acf_extra/airfx/heliinside1.wav differ
diff --git a/sound/acf_extra/airfx/heliinside2.wav b/sound/acf_extra/airfx/heliinside2.wav
new file mode 100644
index 000000000..d05278836
Binary files /dev/null and b/sound/acf_extra/airfx/heliinside2.wav differ
diff --git a/sound/acf_extra/airfx/heliinside3.wav b/sound/acf_extra/airfx/heliinside3.wav
new file mode 100644
index 000000000..60a0a8d81
Binary files /dev/null and b/sound/acf_extra/airfx/heliinside3.wav differ
diff --git a/sound/acf_extra/airfx/heliloopext.wav b/sound/acf_extra/airfx/heliloopext.wav
new file mode 100644
index 000000000..db0b8583e
Binary files /dev/null and b/sound/acf_extra/airfx/heliloopext.wav differ
diff --git a/sound/acf_extra/airfx/heliloopint.wav b/sound/acf_extra/airfx/heliloopint.wav
new file mode 100644
index 000000000..5903db185
Binary files /dev/null and b/sound/acf_extra/airfx/heliloopint.wav differ
diff --git a/sound/acf_extra/airfx/helirotor.wav b/sound/acf_extra/airfx/helirotor.wav
new file mode 100644
index 000000000..e231e9d00
Binary files /dev/null and b/sound/acf_extra/airfx/helirotor.wav differ
diff --git a/sound/acf_extra/airfx/helirotor2.wav b/sound/acf_extra/airfx/helirotor2.wav
new file mode 100644
index 000000000..8ff653e79
Binary files /dev/null and b/sound/acf_extra/airfx/helirotor2.wav differ
diff --git a/sound/acf_extra/airfx/hominglockaquired1.wav b/sound/acf_extra/airfx/hominglockaquired1.wav
new file mode 100644
index 000000000..24935a0df
Binary files /dev/null and b/sound/acf_extra/airfx/hominglockaquired1.wav differ
diff --git a/sound/acf_extra/airfx/hominglocksequence1.wav b/sound/acf_extra/airfx/hominglocksequence1.wav
new file mode 100644
index 000000000..728d4cb6d
Binary files /dev/null and b/sound/acf_extra/airfx/hominglocksequence1.wav differ
diff --git a/sound/acf_extra/airfx/hueyrotors.wav b/sound/acf_extra/airfx/hueyrotors.wav
new file mode 100644
index 000000000..241ab45c2
Binary files /dev/null and b/sound/acf_extra/airfx/hueyrotors.wav differ
diff --git a/sound/acf_extra/airfx/hurricane.wav b/sound/acf_extra/airfx/hurricane.wav
new file mode 100644
index 000000000..ab408b11a
Binary files /dev/null and b/sound/acf_extra/airfx/hurricane.wav differ
diff --git a/sound/acf_extra/airfx/hydr03.wav b/sound/acf_extra/airfx/hydr03.wav
new file mode 100644
index 000000000..2457b3cfa
Binary files /dev/null and b/sound/acf_extra/airfx/hydr03.wav differ
diff --git a/sound/acf_extra/airfx/hydr_geardown.wav b/sound/acf_extra/airfx/hydr_geardown.wav
new file mode 100644
index 000000000..47fd4405c
Binary files /dev/null and b/sound/acf_extra/airfx/hydr_geardown.wav differ
diff --git a/sound/acf_extra/airfx/hydr_gearup.wav b/sound/acf_extra/airfx/hydr_gearup.wav
new file mode 100644
index 000000000..77133656e
Binary files /dev/null and b/sound/acf_extra/airfx/hydr_gearup.wav differ
diff --git a/sound/acf_extra/airfx/javelin.wav b/sound/acf_extra/airfx/javelin.wav
new file mode 100644
index 000000000..aa8d7b0ca
Binary files /dev/null and b/sound/acf_extra/airfx/javelin.wav differ
diff --git a/sound/acf_extra/airfx/javelin_fire.wav b/sound/acf_extra/airfx/javelin_fire.wav
new file mode 100644
index 000000000..f7727b941
Binary files /dev/null and b/sound/acf_extra/airfx/javelin_fire.wav differ
diff --git a/sound/acf_extra/airfx/ju52 (2).wav b/sound/acf_extra/airfx/ju52 (2).wav
new file mode 100644
index 000000000..4f95071d9
Binary files /dev/null and b/sound/acf_extra/airfx/ju52 (2).wav differ
diff --git a/sound/acf_extra/airfx/ju52.wav b/sound/acf_extra/airfx/ju52.wav
new file mode 100644
index 000000000..635040c4f
Binary files /dev/null and b/sound/acf_extra/airfx/ju52.wav differ
diff --git a/sound/acf_extra/airfx/laser_lock.wav b/sound/acf_extra/airfx/laser_lock.wav
new file mode 100644
index 000000000..74a7ad054
Binary files /dev/null and b/sound/acf_extra/airfx/laser_lock.wav differ
diff --git a/sound/acf_extra/airfx/laser_track.wav b/sound/acf_extra/airfx/laser_track.wav
new file mode 100644
index 000000000..a0d346c52
Binary files /dev/null and b/sound/acf_extra/airfx/laser_track.wav differ
diff --git a/sound/acf_extra/airfx/mig29.wav b/sound/acf_extra/airfx/mig29.wav
new file mode 100644
index 000000000..d05af17d0
Binary files /dev/null and b/sound/acf_extra/airfx/mig29.wav differ
diff --git a/sound/acf_extra/airfx/milrotors.wav b/sound/acf_extra/airfx/milrotors.wav
new file mode 100644
index 000000000..4c92b09ba
Binary files /dev/null and b/sound/acf_extra/airfx/milrotors.wav differ
diff --git a/sound/acf_extra/airfx/minoralarm.wav b/sound/acf_extra/airfx/minoralarm.wav
new file mode 100644
index 000000000..6f0b0bade
Binary files /dev/null and b/sound/acf_extra/airfx/minoralarm.wav differ
diff --git a/sound/acf_extra/airfx/missile_launch1.wav b/sound/acf_extra/airfx/missile_launch1.wav
new file mode 100644
index 000000000..aebac1558
Binary files /dev/null and b/sound/acf_extra/airfx/missile_launch1.wav differ
diff --git a/sound/acf_extra/airfx/missile_launch2.wav b/sound/acf_extra/airfx/missile_launch2.wav
new file mode 100644
index 000000000..1d11dbf34
Binary files /dev/null and b/sound/acf_extra/airfx/missile_launch2.wav differ
diff --git a/sound/acf_extra/airfx/missile_launch3.wav b/sound/acf_extra/airfx/missile_launch3.wav
new file mode 100644
index 000000000..97ff57a7f
Binary files /dev/null and b/sound/acf_extra/airfx/missile_launch3.wav differ
diff --git a/sound/acf_extra/airfx/missilenearby.wav b/sound/acf_extra/airfx/missilenearby.wav
new file mode 100644
index 000000000..a20e30d66
Binary files /dev/null and b/sound/acf_extra/airfx/missilenearby.wav differ
diff --git a/sound/acf_extra/airfx/mobile_radar.wav b/sound/acf_extra/airfx/mobile_radar.wav
new file mode 100644
index 000000000..201791e01
Binary files /dev/null and b/sound/acf_extra/airfx/mobile_radar.wav differ
diff --git a/sound/acf_extra/airfx/mtube_launch.wav b/sound/acf_extra/airfx/mtube_launch.wav
new file mode 100644
index 000000000..a9c5cc880
Binary files /dev/null and b/sound/acf_extra/airfx/mtube_launch.wav differ
diff --git a/sound/acf_extra/airfx/orca02.wav b/sound/acf_extra/airfx/orca02.wav
new file mode 100644
index 000000000..705763c02
Binary files /dev/null and b/sound/acf_extra/airfx/orca02.wav differ
diff --git a/sound/acf_extra/airfx/orca_fire.wav b/sound/acf_extra/airfx/orca_fire.wav
new file mode 100644
index 000000000..bc306b5c0
Binary files /dev/null and b/sound/acf_extra/airfx/orca_fire.wav differ
diff --git a/sound/acf_extra/airfx/orca_loop.wav b/sound/acf_extra/airfx/orca_loop.wav
new file mode 100644
index 000000000..cd5654d98
Binary files /dev/null and b/sound/acf_extra/airfx/orca_loop.wav differ
diff --git a/sound/acf_extra/airfx/orcafire1.wav b/sound/acf_extra/airfx/orcafire1.wav
new file mode 100644
index 000000000..7c1fbe121
Binary files /dev/null and b/sound/acf_extra/airfx/orcafire1.wav differ
diff --git a/sound/acf_extra/airfx/p47d (2).wav b/sound/acf_extra/airfx/p47d (2).wav
new file mode 100644
index 000000000..b388bed8e
Binary files /dev/null and b/sound/acf_extra/airfx/p47d (2).wav differ
diff --git a/sound/acf_extra/airfx/p511.wav b/sound/acf_extra/airfx/p511.wav
new file mode 100644
index 000000000..adde29018
Binary files /dev/null and b/sound/acf_extra/airfx/p511.wav differ
diff --git a/sound/acf_extra/airfx/p512.wav b/sound/acf_extra/airfx/p512.wav
new file mode 100644
index 000000000..737c4ab6f
Binary files /dev/null and b/sound/acf_extra/airfx/p512.wav differ
diff --git a/sound/acf_extra/airfx/pipercub (2).wav b/sound/acf_extra/airfx/pipercub (2).wav
new file mode 100644
index 000000000..205e609de
Binary files /dev/null and b/sound/acf_extra/airfx/pipercub (2).wav differ
diff --git a/sound/acf_extra/airfx/pipercub.wav b/sound/acf_extra/airfx/pipercub.wav
new file mode 100644
index 000000000..0ee5dcbcc
Binary files /dev/null and b/sound/acf_extra/airfx/pipercub.wav differ
diff --git a/sound/acf_extra/airfx/radar_lock.wav b/sound/acf_extra/airfx/radar_lock.wav
new file mode 100644
index 000000000..cebf426db
Binary files /dev/null and b/sound/acf_extra/airfx/radar_lock.wav differ
diff --git a/sound/acf_extra/airfx/radar_track.wav b/sound/acf_extra/airfx/radar_track.wav
new file mode 100644
index 000000000..902b6ac56
Binary files /dev/null and b/sound/acf_extra/airfx/radar_track.wav differ
diff --git a/sound/acf_extra/airfx/redsstukaangriff.wav b/sound/acf_extra/airfx/redsstukaangriff.wav
new file mode 100644
index 000000000..91edbc028
Binary files /dev/null and b/sound/acf_extra/airfx/redsstukaangriff.wav differ
diff --git a/sound/acf_extra/airfx/rocket_fire.wav b/sound/acf_extra/airfx/rocket_fire.wav
new file mode 100644
index 000000000..3d1996579
Binary files /dev/null and b/sound/acf_extra/airfx/rocket_fire.wav differ
diff --git a/sound/acf_extra/airfx/rocket_fire2.wav b/sound/acf_extra/airfx/rocket_fire2.wav
new file mode 100644
index 000000000..4a695c65c
Binary files /dev/null and b/sound/acf_extra/airfx/rocket_fire2.wav differ
diff --git a/sound/acf_extra/airfx/rocketbike1.wav b/sound/acf_extra/airfx/rocketbike1.wav
new file mode 100644
index 000000000..c45b6178f
Binary files /dev/null and b/sound/acf_extra/airfx/rocketbike1.wav differ
diff --git a/sound/acf_extra/airfx/rotor_AH64.wav b/sound/acf_extra/airfx/rotor_AH64.wav
new file mode 100644
index 000000000..64ee777de
Binary files /dev/null and b/sound/acf_extra/airfx/rotor_AH64.wav differ
diff --git a/sound/acf_extra/airfx/rotor_Mi17.wav b/sound/acf_extra/airfx/rotor_Mi17.wav
new file mode 100644
index 000000000..762b1f0a3
Binary files /dev/null and b/sound/acf_extra/airfx/rotor_Mi17.wav differ
diff --git a/sound/acf_extra/airfx/rottors.wav b/sound/acf_extra/airfx/rottors.wav
new file mode 100644
index 000000000..490080d7d
Binary files /dev/null and b/sound/acf_extra/airfx/rottors.wav differ
diff --git a/sound/acf_extra/airfx/rpg_fire.wav b/sound/acf_extra/airfx/rpg_fire.wav
new file mode 100644
index 000000000..564f9bfbc
Binary files /dev/null and b/sound/acf_extra/airfx/rpg_fire.wav differ
diff --git a/sound/acf_extra/airfx/s_chinookloop.wav b/sound/acf_extra/airfx/s_chinookloop.wav
new file mode 100644
index 000000000..9467fb651
Binary files /dev/null and b/sound/acf_extra/airfx/s_chinookloop.wav differ
diff --git a/sound/acf_extra/airfx/s_hindloop.wav b/sound/acf_extra/airfx/s_hindloop.wav
new file mode 100644
index 000000000..a2b33fbb3
Binary files /dev/null and b/sound/acf_extra/airfx/s_hindloop.wav differ
diff --git a/sound/acf_extra/airfx/sam_site_fire.wav b/sound/acf_extra/airfx/sam_site_fire.wav
new file mode 100644
index 000000000..3e0491bfc
Binary files /dev/null and b/sound/acf_extra/airfx/sam_site_fire.wav differ
diff --git a/sound/acf_extra/airfx/satellite_target.wav b/sound/acf_extra/airfx/satellite_target.wav
new file mode 100644
index 000000000..33f1568b6
Binary files /dev/null and b/sound/acf_extra/airfx/satellite_target.wav differ
diff --git a/sound/acf_extra/airfx/spitfire (2).wav b/sound/acf_extra/airfx/spitfire (2).wav
new file mode 100644
index 000000000..7f5b265db
Binary files /dev/null and b/sound/acf_extra/airfx/spitfire (2).wav differ
diff --git a/sound/acf_extra/airfx/storch (2).wav b/sound/acf_extra/airfx/storch (2).wav
new file mode 100644
index 000000000..b70dab3a2
Binary files /dev/null and b/sound/acf_extra/airfx/storch (2).wav differ
diff --git a/sound/acf_extra/airfx/stuka (2).wav b/sound/acf_extra/airfx/stuka (2).wav
new file mode 100644
index 000000000..34e615599
Binary files /dev/null and b/sound/acf_extra/airfx/stuka (2).wav differ
diff --git a/sound/acf_extra/airfx/su30.wav b/sound/acf_extra/airfx/su30.wav
new file mode 100644
index 000000000..ea634c1ed
Binary files /dev/null and b/sound/acf_extra/airfx/su30.wav differ
diff --git a/sound/acf_extra/airfx/su34.wav b/sound/acf_extra/airfx/su34.wav
new file mode 100644
index 000000000..c241a8bd9
Binary files /dev/null and b/sound/acf_extra/airfx/su34.wav differ
diff --git a/sound/acf_extra/airfx/swordfish.wav b/sound/acf_extra/airfx/swordfish.wav
new file mode 100644
index 000000000..6bf27c02f
Binary files /dev/null and b/sound/acf_extra/airfx/swordfish.wav differ
diff --git a/sound/acf_extra/airfx/swordfish1.wav b/sound/acf_extra/airfx/swordfish1.wav
new file mode 100644
index 000000000..44223e090
Binary files /dev/null and b/sound/acf_extra/airfx/swordfish1.wav differ
diff --git a/sound/acf_extra/airfx/swordfish2.wav b/sound/acf_extra/airfx/swordfish2.wav
new file mode 100644
index 000000000..8c80d98f1
Binary files /dev/null and b/sound/acf_extra/airfx/swordfish2.wav differ
diff --git a/sound/acf_extra/airfx/tailrottor.wav b/sound/acf_extra/airfx/tailrottor.wav
new file mode 100644
index 000000000..9dcacd7e6
Binary files /dev/null and b/sound/acf_extra/airfx/tailrottor.wav differ
diff --git a/sound/acf_extra/airfx/tow1.wav b/sound/acf_extra/airfx/tow1.wav
new file mode 100644
index 000000000..c256d17e2
Binary files /dev/null and b/sound/acf_extra/airfx/tow1.wav differ
diff --git a/sound/acf_extra/airfx/tow2.wav b/sound/acf_extra/airfx/tow2.wav
new file mode 100644
index 000000000..56fd08722
Binary files /dev/null and b/sound/acf_extra/airfx/tow2.wav differ
diff --git a/sound/acf_extra/airfx/traffichelirotors.wav b/sound/acf_extra/airfx/traffichelirotors.wav
new file mode 100644
index 000000000..c41b230fd
Binary files /dev/null and b/sound/acf_extra/airfx/traffichelirotors.wav differ
diff --git a/sound/acf_extra/airfx/turbo.wav b/sound/acf_extra/airfx/turbo.wav
new file mode 100644
index 000000000..3c0685ce4
Binary files /dev/null and b/sound/acf_extra/airfx/turbo.wav differ
diff --git a/sound/acf_extra/airfx/typhoon (2).wav b/sound/acf_extra/airfx/typhoon (2).wav
new file mode 100644
index 000000000..7d3c1f014
Binary files /dev/null and b/sound/acf_extra/airfx/typhoon (2).wav differ
diff --git a/sound/acf_extra/airfx/typhoon.wav b/sound/acf_extra/airfx/typhoon.wav
new file mode 100644
index 000000000..1cfbc77ee
Binary files /dev/null and b/sound/acf_extra/airfx/typhoon.wav differ
diff --git a/sound/acf_extra/airfx/uh60.wav b/sound/acf_extra/airfx/uh60.wav
new file mode 100644
index 000000000..362894b28
Binary files /dev/null and b/sound/acf_extra/airfx/uh60.wav differ
diff --git a/sound/acf_extra/airfx/usag.wav b/sound/acf_extra/airfx/usag.wav
new file mode 100644
index 000000000..129029742
Binary files /dev/null and b/sound/acf_extra/airfx/usag.wav differ
diff --git a/sound/acf_extra/airfx/weapon_select.wav b/sound/acf_extra/airfx/weapon_select.wav
new file mode 100644
index 000000000..20de5ea52
Binary files /dev/null and b/sound/acf_extra/airfx/weapon_select.wav differ
diff --git a/sound/acf_extra/cockpitfx/F22_engine_idle.wav b/sound/acf_extra/cockpitfx/F22_engine_idle.wav
new file mode 100644
index 000000000..06719131a
Binary files /dev/null and b/sound/acf_extra/cockpitfx/F22_engine_idle.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_altitude.wav b/sound/acf_extra/cockpitfx/betty_altitude.wav
new file mode 100644
index 000000000..38ba0b6c2
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_altitude.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_auto_disengage.wav b/sound/acf_extra/cockpitfx/betty_auto_disengage.wav
new file mode 100644
index 000000000..dfa39233c
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_auto_disengage.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_auto_engage.wav b/sound/acf_extra/cockpitfx/betty_auto_engage.wav
new file mode 100644
index 000000000..c7d0c4d5a
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_auto_engage.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_auto_heading.wav b/sound/acf_extra/cockpitfx/betty_auto_heading.wav
new file mode 100644
index 000000000..75001d99e
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_auto_heading.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_auto_recovery.wav b/sound/acf_extra/cockpitfx/betty_auto_recovery.wav
new file mode 100644
index 000000000..3c3ad8db3
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_auto_recovery.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_auto_throttle.wav b/sound/acf_extra/cockpitfx/betty_auto_throttle.wav
new file mode 100644
index 000000000..cb5bd0f18
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_auto_throttle.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_auto_track.wav b/sound/acf_extra/cockpitfx/betty_auto_track.wav
new file mode 100644
index 000000000..7d4b157be
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_auto_track.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_auto_waypoint.wav b/sound/acf_extra/cockpitfx/betty_auto_waypoint.wav
new file mode 100644
index 000000000..06b05cb90
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_auto_waypoint.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_counter_chaff.wav b/sound/acf_extra/cockpitfx/betty_counter_chaff.wav
new file mode 100644
index 000000000..28f32915b
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_counter_chaff.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_counter_decoy.wav b/sound/acf_extra/cockpitfx/betty_counter_decoy.wav
new file mode 100644
index 000000000..24aaa37e1
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_counter_decoy.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_counter_flare.wav b/sound/acf_extra/cockpitfx/betty_counter_flare.wav
new file mode 100644
index 000000000..ab61c4bae
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_counter_flare.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_data.wav b/sound/acf_extra/cockpitfx/betty_data.wav
new file mode 100644
index 000000000..13a8c1fac
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_data.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_datafail.wav b/sound/acf_extra/cockpitfx/betty_datafail.wav
new file mode 100644
index 000000000..b70171d44
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_datafail.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_a1.wav b/sound/acf_extra/cockpitfx/betty_emcon_a1.wav
new file mode 100644
index 000000000..694e113ff
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_a1.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_a2.wav b/sound/acf_extra/cockpitfx/betty_emcon_a2.wav
new file mode 100644
index 000000000..cd72ca536
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_a2.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_a3.wav b/sound/acf_extra/cockpitfx/betty_emcon_a3.wav
new file mode 100644
index 000000000..27f0d9c28
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_a3.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_a4.wav b/sound/acf_extra/cockpitfx/betty_emcon_a4.wav
new file mode 100644
index 000000000..bc9c6f4db
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_a4.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_a5.wav b/sound/acf_extra/cockpitfx/betty_emcon_a5.wav
new file mode 100644
index 000000000..b01b69f50
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_a5.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_advisor.wav b/sound/acf_extra/cockpitfx/betty_emcon_advisor.wav
new file mode 100644
index 000000000..d7a9eea1f
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_advisor.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_m1.wav b/sound/acf_extra/cockpitfx/betty_emcon_m1.wav
new file mode 100644
index 000000000..8221d1c61
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_m1.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_m2.wav b/sound/acf_extra/cockpitfx/betty_emcon_m2.wav
new file mode 100644
index 000000000..f51276213
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_m2.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_m3.wav b/sound/acf_extra/cockpitfx/betty_emcon_m3.wav
new file mode 100644
index 000000000..35cb12778
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_m3.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_m4.wav b/sound/acf_extra/cockpitfx/betty_emcon_m4.wav
new file mode 100644
index 000000000..00ba7df80
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_m4.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_emcon_m5.wav b/sound/acf_extra/cockpitfx/betty_emcon_m5.wav
new file mode 100644
index 000000000..2be1af535
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_emcon_m5.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_engine_leftfail.wav b/sound/acf_extra/cockpitfx/betty_engine_leftfail.wav
new file mode 100644
index 000000000..fb64a7602
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_engine_leftfail.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_engine_rightfail.wav b/sound/acf_extra/cockpitfx/betty_engine_rightfail.wav
new file mode 100644
index 000000000..55f5d2aa5
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_engine_rightfail.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_fast.wav b/sound/acf_extra/cockpitfx/betty_fast.wav
new file mode 100644
index 000000000..c1de18711
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_fast.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_fuel_bingo.wav b/sound/acf_extra/cockpitfx/betty_fuel_bingo.wav
new file mode 100644
index 000000000..c6665c05f
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_fuel_bingo.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_fuel_drop.wav b/sound/acf_extra/cockpitfx/betty_fuel_drop.wav
new file mode 100644
index 000000000..1fdf035e9
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_fuel_drop.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_fuel_extlow.wav b/sound/acf_extra/cockpitfx/betty_fuel_extlow.wav
new file mode 100644
index 000000000..c66d76f24
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_fuel_extlow.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_fuel_low.wav b/sound/acf_extra/cockpitfx/betty_fuel_low.wav
new file mode 100644
index 000000000..56df2dc24
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_fuel_low.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_geardown.wav b/sound/acf_extra/cockpitfx/betty_geardown.wav
new file mode 100644
index 000000000..435e7d505
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_geardown.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_gearup.wav b/sound/acf_extra/cockpitfx/betty_gearup.wav
new file mode 100644
index 000000000..c61c4d8a6
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_gearup.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_heading.wav b/sound/acf_extra/cockpitfx/betty_heading.wav
new file mode 100644
index 000000000..e089445b5
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_heading.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_high.wav b/sound/acf_extra/cockpitfx/betty_high.wav
new file mode 100644
index 000000000..23a1e3dff
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_high.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_ils_apr.wav b/sound/acf_extra/cockpitfx/betty_ils_apr.wav
new file mode 100644
index 000000000..9d3a4fc7d
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_ils_apr.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_left.wav b/sound/acf_extra/cockpitfx/betty_left.wav
new file mode 100644
index 000000000..8782de920
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_left.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_low.wav b/sound/acf_extra/cockpitfx/betty_low.wav
new file mode 100644
index 000000000..18467061c
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_low.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_missile_locked.wav b/sound/acf_extra/cockpitfx/betty_missile_locked.wav
new file mode 100644
index 000000000..da0ea482a
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_missile_locked.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_missile_neglock.wav b/sound/acf_extra/cockpitfx/betty_missile_neglock.wav
new file mode 100644
index 000000000..8402e362c
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_missile_neglock.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_missile_negsolution.wav b/sound/acf_extra/cockpitfx/betty_missile_negsolution.wav
new file mode 100644
index 000000000..2f35d5612
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_missile_negsolution.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_mongo_engage.wav b/sound/acf_extra/cockpitfx/betty_mongo_engage.wav
new file mode 100644
index 000000000..d2e35111c
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_mongo_engage.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_negid.wav b/sound/acf_extra/cockpitfx/betty_negid.wav
new file mode 100644
index 000000000..b373c6407
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_negid.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_negparam.wav b/sound/acf_extra/cockpitfx/betty_negparam.wav
new file mode 100644
index 000000000..1ee34c806
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_negparam.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_range.wav b/sound/acf_extra/cockpitfx/betty_range.wav
new file mode 100644
index 000000000..a69f2f753
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_range.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_right.wav b/sound/acf_extra/cockpitfx/betty_right.wav
new file mode 100644
index 000000000..96ba4ed98
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_right.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_shoot.wav b/sound/acf_extra/cockpitfx/betty_shoot.wav
new file mode 100644
index 000000000..9b4d19d22
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_shoot.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_slow.wav b/sound/acf_extra/cockpitfx/betty_slow.wav
new file mode 100644
index 000000000..1e1b234f6
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_slow.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_speed.wav b/sound/acf_extra/cockpitfx/betty_speed.wav
new file mode 100644
index 000000000..daa835a9a
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_speed.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_avionicscfg.wav b/sound/acf_extra/cockpitfx/betty_warn_avionicscfg.wav
new file mode 100644
index 000000000..1891edbc2
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_avionicscfg.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_avionicsfail.wav b/sound/acf_extra/cockpitfx/betty_warn_avionicsfail.wav
new file mode 100644
index 000000000..4d2ff2665
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_avionicsfail.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_electricfail.wav b/sound/acf_extra/cockpitfx/betty_warn_electricfail.wav
new file mode 100644
index 000000000..3ef3a6912
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_electricfail.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_flight_limit.wav b/sound/acf_extra/cockpitfx/betty_warn_flight_limit.wav
new file mode 100644
index 000000000..70f8ae63c
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_flight_limit.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_fuelfail.wav b/sound/acf_extra/cockpitfx/betty_warn_fuelfail.wav
new file mode 100644
index 000000000..bb93f549a
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_fuelfail.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_ground.wav b/sound/acf_extra/cockpitfx/betty_warn_ground.wav
new file mode 100644
index 000000000..f3a9afa16
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_ground.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_hydrofail.wav b/sound/acf_extra/cockpitfx/betty_warn_hydrofail.wav
new file mode 100644
index 000000000..f47be5282
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_hydrofail.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_launchmis.wav b/sound/acf_extra/cockpitfx/betty_warn_launchmis.wav
new file mode 100644
index 000000000..e9146880e
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_launchmis.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_launchsam.wav b/sound/acf_extra/cockpitfx/betty_warn_launchsam.wav
new file mode 100644
index 000000000..acfa9ac11
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_launchsam.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_negverb.wav b/sound/acf_extra/cockpitfx/betty_warn_negverb.wav
new file mode 100644
index 000000000..7263e25b2
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_negverb.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_noise.wav b/sound/acf_extra/cockpitfx/betty_warn_noise.wav
new file mode 100644
index 000000000..1c0a4c893
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_noise.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_radar_isock.wav b/sound/acf_extra/cockpitfx/betty_warn_radar_isock.wav
new file mode 100644
index 000000000..b21a1c43f
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_radar_isock.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_radar_search.wav b/sound/acf_extra/cockpitfx/betty_warn_radar_search.wav
new file mode 100644
index 000000000..cedd0ef6d
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_radar_search.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_radarlock.wav b/sound/acf_extra/cockpitfx/betty_warn_radarlock.wav
new file mode 100644
index 000000000..780b11234
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_radarlock.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_samlock.wav b/sound/acf_extra/cockpitfx/betty_warn_samlock.wav
new file mode 100644
index 000000000..990813e08
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_samlock.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_warn_speedbrake.wav b/sound/acf_extra/cockpitfx/betty_warn_speedbrake.wav
new file mode 100644
index 000000000..6666104bd
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_warn_speedbrake.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_waypoint.wav b/sound/acf_extra/cockpitfx/betty_waypoint.wav
new file mode 100644
index 000000000..49990b039
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_waypoint.wav differ
diff --git a/sound/acf_extra/cockpitfx/betty_wingman_display.wav b/sound/acf_extra/cockpitfx/betty_wingman_display.wav
new file mode 100644
index 000000000..1b353069e
Binary files /dev/null and b/sound/acf_extra/cockpitfx/betty_wingman_display.wav differ
diff --git a/sound/acf_extra/miscfx/polis.wav b/sound/acf_extra/miscfx/polis.wav
new file mode 100644
index 000000000..0e00d2122
Binary files /dev/null and b/sound/acf_extra/miscfx/polis.wav differ
diff --git a/sound/acf_extra/miscfx/siren.wav b/sound/acf_extra/miscfx/siren.wav
new file mode 100644
index 000000000..1acd5bd60
Binary files /dev/null and b/sound/acf_extra/miscfx/siren.wav differ
diff --git a/sound/acf_extra/tankfx/1974_tracks.wav b/sound/acf_extra/tankfx/1974_tracks.wav
new file mode 100644
index 000000000..6ac7489f3
Binary files /dev/null and b/sound/acf_extra/tankfx/1974_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/20mm_01.wav b/sound/acf_extra/tankfx/20mm_01.wav
new file mode 100644
index 000000000..b2b781fc2
Binary files /dev/null and b/sound/acf_extra/tankfx/20mm_01.wav differ
diff --git a/sound/acf_extra/tankfx/20mm_02.wav b/sound/acf_extra/tankfx/20mm_02.wav
new file mode 100644
index 000000000..fb4b18073
Binary files /dev/null and b/sound/acf_extra/tankfx/20mm_02.wav differ
diff --git a/sound/acf_extra/tankfx/20mm_03.wav b/sound/acf_extra/tankfx/20mm_03.wav
new file mode 100644
index 000000000..4aedf29a7
Binary files /dev/null and b/sound/acf_extra/tankfx/20mm_03.wav differ
diff --git a/sound/acf_extra/tankfx/20mm_04.wav b/sound/acf_extra/tankfx/20mm_04.wav
new file mode 100644
index 000000000..106d805f9
Binary files /dev/null and b/sound/acf_extra/tankfx/20mm_04.wav differ
diff --git a/sound/acf_extra/tankfx/20mm_05.wav b/sound/acf_extra/tankfx/20mm_05.wav
new file mode 100644
index 000000000..4c56e92d2
Binary files /dev/null and b/sound/acf_extra/tankfx/20mm_05.wav differ
diff --git a/sound/acf_extra/tankfx/MAD.wav b/sound/acf_extra/tankfx/MAD.wav
new file mode 100644
index 000000000..d26d44809
Binary files /dev/null and b/sound/acf_extra/tankfx/MAD.wav differ
diff --git a/sound/acf_extra/tankfx/abrams_tracks.wav b/sound/acf_extra/tankfx/abrams_tracks.wav
new file mode 100644
index 000000000..70bda21f4
Binary files /dev/null and b/sound/acf_extra/tankfx/abrams_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/bmp_tracks.wav b/sound/acf_extra/tankfx/bmp_tracks.wav
new file mode 100644
index 000000000..38ba3e8a6
Binary files /dev/null and b/sound/acf_extra/tankfx/bmp_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/carriage.wav b/sound/acf_extra/tankfx/carriage.wav
new file mode 100644
index 000000000..5150754fa
Binary files /dev/null and b/sound/acf_extra/tankfx/carriage.wav differ
diff --git a/sound/acf_extra/tankfx/clunk.wav b/sound/acf_extra/tankfx/clunk.wav
new file mode 100644
index 000000000..11a3be8b0
Binary files /dev/null and b/sound/acf_extra/tankfx/clunk.wav differ
diff --git a/sound/acf_extra/tankfx/concretetread.wav b/sound/acf_extra/tankfx/concretetread.wav
new file mode 100644
index 000000000..74fe44304
Binary files /dev/null and b/sound/acf_extra/tankfx/concretetread.wav differ
diff --git a/sound/acf_extra/tankfx/dirttread.wav b/sound/acf_extra/tankfx/dirttread.wav
new file mode 100644
index 000000000..f3be6210e
Binary files /dev/null and b/sound/acf_extra/tankfx/dirttread.wav differ
diff --git a/sound/acf_extra/tankfx/energy/gauss-automatic.wav b/sound/acf_extra/tankfx/energy/gauss-automatic.wav
new file mode 100644
index 000000000..a74caa22e
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/gauss-automatic.wav differ
diff --git a/sound/acf_extra/tankfx/energy/gauss-cannon.wav b/sound/acf_extra/tankfx/energy/gauss-cannon.wav
new file mode 100644
index 000000000..a2b8c3ad9
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/gauss-cannon.wav differ
diff --git a/sound/acf_extra/tankfx/energy/laser-automatic.wav b/sound/acf_extra/tankfx/energy/laser-automatic.wav
new file mode 100644
index 000000000..6277b9f04
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/laser-automatic.wav differ
diff --git a/sound/acf_extra/tankfx/energy/laser-cannon.wav b/sound/acf_extra/tankfx/energy/laser-cannon.wav
new file mode 100644
index 000000000..4e24ab4af
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/laser-cannon.wav differ
diff --git a/sound/acf_extra/tankfx/energy/plasma-automatic.wav b/sound/acf_extra/tankfx/energy/plasma-automatic.wav
new file mode 100644
index 000000000..ced9dd2db
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/plasma-automatic.wav differ
diff --git a/sound/acf_extra/tankfx/energy/plasma-cannon.wav b/sound/acf_extra/tankfx/energy/plasma-cannon.wav
new file mode 100644
index 000000000..431cff6b0
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/plasma-cannon.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_advlaserpistol_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_advlaserpistol_fire_2d.wav
new file mode 100644
index 000000000..6aa6359b0
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_advlaserpistol_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_advlaserpistol_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_advlaserpistol_fire_3d.wav
new file mode 100644
index 000000000..1ee5e6305
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_advlaserpistol_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_advlaserrifle_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_advlaserrifle_fire_2d.wav
new file mode 100644
index 000000000..2f86548bc
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_advlaserrifle_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_emppistol_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_emppistol_fire_2d.wav
new file mode 100644
index 000000000..74b4014bd
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_emppistol_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_emppistol_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_emppistol_fire_3d.wav
new file mode 100644
index 000000000..d4b5bb546
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_emppistol_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_gausspistol_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_gausspistol_fire_3d.wav
new file mode 100644
index 000000000..63116e6d0
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_gausspistol_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_gaussrifle_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_gaussrifle_fire_3d.wav
new file mode 100644
index 000000000..5f1f18f31
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_gaussrifle_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_laserblaster_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_laserblaster_fire_2d.wav
new file mode 100644
index 000000000..348b8a6eb
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_laserblaster_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_laserblaster_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_laserblaster_fire_3d.wav
new file mode 100644
index 000000000..c4feead61
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_laserblaster_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_lasersniper_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_lasersniper_fire_3d.wav
new file mode 100644
index 000000000..c3b41b8d4
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_lasersniper_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_mecgm_dry.wav b/sound/acf_extra/tankfx/energy/wpn_mecgm_dry.wav
new file mode 100644
index 000000000..63384c0f7
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_mecgm_dry.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_mecgm_spin.wav b/sound/acf_extra/tankfx/energy/wpn_mecgm_spin.wav
new file mode 100644
index 000000000..3ccd440b5
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_mecgm_spin.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_pistolplasma2_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_pistolplasma2_fire_3d.wav
new file mode 100644
index 000000000..ca4dc00cd
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_pistolplasma2_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_pistolplasma2_reload.wav b/sound/acf_extra/tankfx/energy/wpn_pistolplasma2_reload.wav
new file mode 100644
index 000000000..b0dfa7d3e
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_pistolplasma2_reload.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_pistolplasmag86_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_pistolplasmag86_fire_2d.wav
new file mode 100644
index 000000000..828f6079f
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_pistolplasmag86_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_pistolplasmag86_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_pistolplasmag86_fire_3d.wav
new file mode 100644
index 000000000..018529500
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_pistolplasmag86_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_plasmagatling_spin.wav b/sound/acf_extra/tankfx/energy/wpn_plasmagatling_spin.wav
new file mode 100644
index 000000000..ba1feea41
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_plasmagatling_spin.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_pulserifle_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_pulserifle_fire_2d.wav
new file mode 100644
index 000000000..882db4d60
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_pulserifle_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_pulserifle_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_pulserifle_fire_3d.wav
new file mode 100644
index 000000000..1992d2811
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_pulserifle_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_supersonicrifle_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_supersonicrifle_fire_2d.wav
new file mode 100644
index 000000000..437fbbd34
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_supersonicrifle_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_supersonicrifle_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_supersonicrifle_fire_3d.wav
new file mode 100644
index 000000000..d2076769b
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_supersonicrifle_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_wattzpistol_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_wattzpistol_fire_2d.wav
new file mode 100644
index 000000000..197577e57
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_wattzpistol_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_wattzpistol_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_wattzpistol_fire_3d.wav
new file mode 100644
index 000000000..d0565133b
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_wattzpistol_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_wattzrifle_fire_2d.wav b/sound/acf_extra/tankfx/energy/wpn_wattzrifle_fire_2d.wav
new file mode 100644
index 000000000..97855e054
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_wattzrifle_fire_2d.wav differ
diff --git a/sound/acf_extra/tankfx/energy/wpn_wattzrifle_fire_3d.wav b/sound/acf_extra/tankfx/energy/wpn_wattzrifle_fire_3d.wav
new file mode 100644
index 000000000..8d4b948eb
Binary files /dev/null and b/sound/acf_extra/tankfx/energy/wpn_wattzrifle_fire_3d.wav differ
diff --git a/sound/acf_extra/tankfx/flare_launch.wav b/sound/acf_extra/tankfx/flare_launch.wav
new file mode 100644
index 000000000..02691c0b4
Binary files /dev/null and b/sound/acf_extra/tankfx/flare_launch.wav differ
diff --git a/sound/acf_extra/tankfx/gepard_tracks.wav b/sound/acf_extra/tankfx/gepard_tracks.wav
new file mode 100644
index 000000000..2bec109ed
Binary files /dev/null and b/sound/acf_extra/tankfx/gepard_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/glasstread.wav b/sound/acf_extra/tankfx/glasstread.wav
new file mode 100644
index 000000000..5ff859465
Binary files /dev/null and b/sound/acf_extra/tankfx/glasstread.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/100mm1.wav b/sound/acf_extra/tankfx/gnomefather/100mm1.wav
new file mode 100644
index 000000000..b1e81ac29
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/100mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/100mm2.wav b/sound/acf_extra/tankfx/gnomefather/100mm2.wav
new file mode 100644
index 000000000..6cc2493c4
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/100mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/100mm3.wav b/sound/acf_extra/tankfx/gnomefather/100mm3.wav
new file mode 100644
index 000000000..366265a8c
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/100mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/100mm4.wav b/sound/acf_extra/tankfx/gnomefather/100mm4.wav
new file mode 100644
index 000000000..d1e4338f0
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/100mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/105mm1.wav b/sound/acf_extra/tankfx/gnomefather/105mm1.wav
new file mode 100644
index 000000000..b2cc4cdcb
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/105mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/105mm2.wav b/sound/acf_extra/tankfx/gnomefather/105mm2.wav
new file mode 100644
index 000000000..9fffc390a
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/105mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/105mm4.wav b/sound/acf_extra/tankfx/gnomefather/105mm4.wav
new file mode 100644
index 000000000..fb6407682
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/105mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/105mm5.wav b/sound/acf_extra/tankfx/gnomefather/105mm5.wav
new file mode 100644
index 000000000..44ff4ff35
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/105mm5.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/105mm6.wav b/sound/acf_extra/tankfx/gnomefather/105mm6.wav
new file mode 100644
index 000000000..a171934e1
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/105mm6.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/105mm7.wav b/sound/acf_extra/tankfx/gnomefather/105mm7.wav
new file mode 100644
index 000000000..5a99954a1
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/105mm7.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/105mm8.wav b/sound/acf_extra/tankfx/gnomefather/105mm8.wav
new file mode 100644
index 000000000..a3419bcc1
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/105mm8.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/107mm1.wav b/sound/acf_extra/tankfx/gnomefather/107mm1.wav
new file mode 100644
index 000000000..820d77c2a
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/107mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/120mm1.wav b/sound/acf_extra/tankfx/gnomefather/120mm1.wav
new file mode 100644
index 000000000..8131c2b15
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/120mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/120mm2.wav b/sound/acf_extra/tankfx/gnomefather/120mm2.wav
new file mode 100644
index 000000000..222bfd2d1
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/120mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/120mm3.wav b/sound/acf_extra/tankfx/gnomefather/120mm3.wav
new file mode 100644
index 000000000..d17c31004
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/120mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/122mm1.wav b/sound/acf_extra/tankfx/gnomefather/122mm1.wav
new file mode 100644
index 000000000..13fb2babb
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/122mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/122mm2.wav b/sound/acf_extra/tankfx/gnomefather/122mm2.wav
new file mode 100644
index 000000000..c94275708
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/122mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/122mm3.wav b/sound/acf_extra/tankfx/gnomefather/122mm3.wav
new file mode 100644
index 000000000..8b6136eb9
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/122mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/122mm4.wav b/sound/acf_extra/tankfx/gnomefather/122mm4.wav
new file mode 100644
index 000000000..c70282cfa
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/122mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/128mm1.wav b/sound/acf_extra/tankfx/gnomefather/128mm1.wav
new file mode 100644
index 000000000..84269d9a3
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/128mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/12mm1.wav b/sound/acf_extra/tankfx/gnomefather/12mm1.wav
new file mode 100644
index 000000000..96197c702
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/12mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/12mm2.wav b/sound/acf_extra/tankfx/gnomefather/12mm2.wav
new file mode 100644
index 000000000..21290642a
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/12mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/130mm1.wav b/sound/acf_extra/tankfx/gnomefather/130mm1.wav
new file mode 100644
index 000000000..5c33607c9
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/130mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/13mm1.wav b/sound/acf_extra/tankfx/gnomefather/13mm1.wav
new file mode 100644
index 000000000..6fc7c58cf
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/13mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/14mm1.wav b/sound/acf_extra/tankfx/gnomefather/14mm1.wav
new file mode 100644
index 000000000..62717130b
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/14mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/150mm1.wav b/sound/acf_extra/tankfx/gnomefather/150mm1.wav
new file mode 100644
index 000000000..2aa0abbf3
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/150mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/152mm1.wav b/sound/acf_extra/tankfx/gnomefather/152mm1.wav
new file mode 100644
index 000000000..2cb07928c
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/152mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/152mm2.wav b/sound/acf_extra/tankfx/gnomefather/152mm2.wav
new file mode 100644
index 000000000..e1ad581a9
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/152mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/152mm3.wav b/sound/acf_extra/tankfx/gnomefather/152mm3.wav
new file mode 100644
index 000000000..4ba569a56
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/152mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/152mm4.wav b/sound/acf_extra/tankfx/gnomefather/152mm4.wav
new file mode 100644
index 000000000..6697cda68
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/152mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/152mm5.wav b/sound/acf_extra/tankfx/gnomefather/152mm5.wav
new file mode 100644
index 000000000..6b3c575c0
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/152mm5.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/155mm1.wav b/sound/acf_extra/tankfx/gnomefather/155mm1.wav
new file mode 100644
index 000000000..fe7dd6067
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/155mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/155mm2.wav b/sound/acf_extra/tankfx/gnomefather/155mm2.wav
new file mode 100644
index 000000000..fe7dd6067
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/155mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/155mm3.wav b/sound/acf_extra/tankfx/gnomefather/155mm3.wav
new file mode 100644
index 000000000..494569083
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/155mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/170mm1.wav b/sound/acf_extra/tankfx/gnomefather/170mm1.wav
new file mode 100644
index 000000000..db22c7048
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/170mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/170mm2.wav b/sound/acf_extra/tankfx/gnomefather/170mm2.wav
new file mode 100644
index 000000000..6ccf260fe
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/170mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/17pdr1.wav b/sound/acf_extra/tankfx/gnomefather/17pdr1.wav
new file mode 100644
index 000000000..e70985753
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/17pdr1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/17pdr2.wav b/sound/acf_extra/tankfx/gnomefather/17pdr2.wav
new file mode 100644
index 000000000..ec5838cfb
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/17pdr2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/203mm1.wav b/sound/acf_extra/tankfx/gnomefather/203mm1.wav
new file mode 100644
index 000000000..d8d5082a3
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/203mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/20pdr1.wav b/sound/acf_extra/tankfx/gnomefather/20pdr1.wav
new file mode 100644
index 000000000..e17847f24
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/20pdr1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/20pdr2.wav b/sound/acf_extra/tankfx/gnomefather/20pdr2.wav
new file mode 100644
index 000000000..21e3c3542
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/20pdr2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/20pdr3.wav b/sound/acf_extra/tankfx/gnomefather/20pdr3.wav
new file mode 100644
index 000000000..aba104c10
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/20pdr3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/210mm1.wav b/sound/acf_extra/tankfx/gnomefather/210mm1.wav
new file mode 100644
index 000000000..109edf0fd
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/210mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/240mm1.wav b/sound/acf_extra/tankfx/gnomefather/240mm1.wav
new file mode 100644
index 000000000..d3eb1893c
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/240mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/25mm1.wav b/sound/acf_extra/tankfx/gnomefather/25mm1.wav
new file mode 100644
index 000000000..073cbabba
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/25mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/25mm2.wav b/sound/acf_extra/tankfx/gnomefather/25mm2.wav
new file mode 100644
index 000000000..5b687de41
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/25mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/25pdr1.wav b/sound/acf_extra/tankfx/gnomefather/25pdr1.wav
new file mode 100644
index 000000000..914bb2c00
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/25pdr1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/25pdr2.wav b/sound/acf_extra/tankfx/gnomefather/25pdr2.wav
new file mode 100644
index 000000000..c13d76d6e
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/25pdr2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/2pdr1.wav b/sound/acf_extra/tankfx/gnomefather/2pdr1.wav
new file mode 100644
index 000000000..550efec51
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/2pdr1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/2pdr2.wav b/sound/acf_extra/tankfx/gnomefather/2pdr2.wav
new file mode 100644
index 000000000..42ed0c351
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/2pdr2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/32pdr1.wav b/sound/acf_extra/tankfx/gnomefather/32pdr1.wav
new file mode 100644
index 000000000..b23bf5b63
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/32pdr1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/32pdr2.wav b/sound/acf_extra/tankfx/gnomefather/32pdr2.wav
new file mode 100644
index 000000000..c0ad57749
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/32pdr2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/37mm1.wav b/sound/acf_extra/tankfx/gnomefather/37mm1.wav
new file mode 100644
index 000000000..345d3ff9c
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/37mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/37mm2.wav b/sound/acf_extra/tankfx/gnomefather/37mm2.wav
new file mode 100644
index 000000000..8f6ba0e19
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/37mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/37mm3.wav b/sound/acf_extra/tankfx/gnomefather/37mm3.wav
new file mode 100644
index 000000000..6e6826172
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/37mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/37mm4.wav b/sound/acf_extra/tankfx/gnomefather/37mm4.wav
new file mode 100644
index 000000000..b646503c1
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/37mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/37mm5.wav b/sound/acf_extra/tankfx/gnomefather/37mm5.wav
new file mode 100644
index 000000000..aeacd2c3d
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/37mm5.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/37mm6.wav b/sound/acf_extra/tankfx/gnomefather/37mm6.wav
new file mode 100644
index 000000000..ae3957ad9
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/37mm6.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/40mm1.wav b/sound/acf_extra/tankfx/gnomefather/40mm1.wav
new file mode 100644
index 000000000..906764d2e
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/40mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/40mm2.wav b/sound/acf_extra/tankfx/gnomefather/40mm2.wav
new file mode 100644
index 000000000..1ce094493
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/40mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/40mm3.wav b/sound/acf_extra/tankfx/gnomefather/40mm3.wav
new file mode 100644
index 000000000..ac04ac0d0
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/40mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/40mm4.wav b/sound/acf_extra/tankfx/gnomefather/40mm4.wav
new file mode 100644
index 000000000..328a9ee3b
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/40mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/45mm1.wav b/sound/acf_extra/tankfx/gnomefather/45mm1.wav
new file mode 100644
index 000000000..699094dba
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/45mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/50mm1.wav b/sound/acf_extra/tankfx/gnomefather/50mm1.wav
new file mode 100644
index 000000000..53d158d0e
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/50mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/50mm2.wav b/sound/acf_extra/tankfx/gnomefather/50mm2.wav
new file mode 100644
index 000000000..e29234315
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/50mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/57mm1.wav b/sound/acf_extra/tankfx/gnomefather/57mm1.wav
new file mode 100644
index 000000000..002d198ba
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/57mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/57mm2.wav b/sound/acf_extra/tankfx/gnomefather/57mm2.wav
new file mode 100644
index 000000000..725184b11
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/57mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/6pdr1.wav b/sound/acf_extra/tankfx/gnomefather/6pdr1.wav
new file mode 100644
index 000000000..ebe5df25e
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/6pdr1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/6pdr2.wav b/sound/acf_extra/tankfx/gnomefather/6pdr2.wav
new file mode 100644
index 000000000..edb1bc801
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/6pdr2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/6pdr3.wav b/sound/acf_extra/tankfx/gnomefather/6pdr3.wav
new file mode 100644
index 000000000..bfdd9f886
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/6pdr3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/6pdr4.wav b/sound/acf_extra/tankfx/gnomefather/6pdr4.wav
new file mode 100644
index 000000000..fb09089dc
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/6pdr4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/75mm1.wav b/sound/acf_extra/tankfx/gnomefather/75mm1.wav
new file mode 100644
index 000000000..96e03fc38
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/75mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/75mm2.wav b/sound/acf_extra/tankfx/gnomefather/75mm2.wav
new file mode 100644
index 000000000..9654bc211
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/75mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/75mm3.wav b/sound/acf_extra/tankfx/gnomefather/75mm3.wav
new file mode 100644
index 000000000..2db316656
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/75mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/75mm4.wav b/sound/acf_extra/tankfx/gnomefather/75mm4.wav
new file mode 100644
index 000000000..624497f12
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/75mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/76mm1.wav b/sound/acf_extra/tankfx/gnomefather/76mm1.wav
new file mode 100644
index 000000000..f1e85c323
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/76mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/76mm2.wav b/sound/acf_extra/tankfx/gnomefather/76mm2.wav
new file mode 100644
index 000000000..c73384f5a
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/76mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/76mm3.wav b/sound/acf_extra/tankfx/gnomefather/76mm3.wav
new file mode 100644
index 000000000..dd141d821
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/76mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/76mm4.wav b/sound/acf_extra/tankfx/gnomefather/76mm4.wav
new file mode 100644
index 000000000..c73384f5a
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/76mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/76mm5.wav b/sound/acf_extra/tankfx/gnomefather/76mm5.wav
new file mode 100644
index 000000000..d61a6dd57
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/76mm5.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/7mm1.wav b/sound/acf_extra/tankfx/gnomefather/7mm1.wav
new file mode 100644
index 000000000..f100fc993
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/7mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/7mm2.wav b/sound/acf_extra/tankfx/gnomefather/7mm2.wav
new file mode 100644
index 000000000..ab0705ee3
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/7mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/85mm1.wav b/sound/acf_extra/tankfx/gnomefather/85mm1.wav
new file mode 100644
index 000000000..fb65ddcaf
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/85mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/85mm2.wav b/sound/acf_extra/tankfx/gnomefather/85mm2.wav
new file mode 100644
index 000000000..0669e8c4c
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/85mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/88mm1.wav b/sound/acf_extra/tankfx/gnomefather/88mm1.wav
new file mode 100644
index 000000000..590fbb61f
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/88mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/88mm2.wav b/sound/acf_extra/tankfx/gnomefather/88mm2.wav
new file mode 100644
index 000000000..88a4abc20
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/88mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/88mm3.wav b/sound/acf_extra/tankfx/gnomefather/88mm3.wav
new file mode 100644
index 000000000..d773dadfd
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/88mm3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/88mm4.wav b/sound/acf_extra/tankfx/gnomefather/88mm4.wav
new file mode 100644
index 000000000..1a5ff5817
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/88mm4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/88mm5.wav b/sound/acf_extra/tankfx/gnomefather/88mm5.wav
new file mode 100644
index 000000000..e2e85b12b
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/88mm5.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/88mm6.wav b/sound/acf_extra/tankfx/gnomefather/88mm6.wav
new file mode 100644
index 000000000..c338f1c85
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/88mm6.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/8mm1.wav b/sound/acf_extra/tankfx/gnomefather/8mm1.wav
new file mode 100644
index 000000000..b2ad7d26e
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/8mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/8mm2.wav b/sound/acf_extra/tankfx/gnomefather/8mm2.wav
new file mode 100644
index 000000000..6b4aadb7b
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/8mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/90mm1.wav b/sound/acf_extra/tankfx/gnomefather/90mm1.wav
new file mode 100644
index 000000000..bf8cd8f6f
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/90mm1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/90mm2.wav b/sound/acf_extra/tankfx/gnomefather/90mm2.wav
new file mode 100644
index 000000000..67a53d177
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/90mm2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/autoloader1.wav b/sound/acf_extra/tankfx/gnomefather/autoloader1.wav
new file mode 100644
index 000000000..a0fa314ff
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/autoloader1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/autoloader2.wav b/sound/acf_extra/tankfx/gnomefather/autoloader2.wav
new file mode 100644
index 000000000..64fd401be
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/autoloader2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/autoloader3.wav b/sound/acf_extra/tankfx/gnomefather/autoloader3.wav
new file mode 100644
index 000000000..f9a146325
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/autoloader3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/autoloader4.wav b/sound/acf_extra/tankfx/gnomefather/autoloader4.wav
new file mode 100644
index 000000000..572f623c6
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/autoloader4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/autoloader5.wav b/sound/acf_extra/tankfx/gnomefather/autoloader5.wav
new file mode 100644
index 000000000..20f0fb432
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/autoloader5.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/autoloader6.wav b/sound/acf_extra/tankfx/gnomefather/autoloader6.wav
new file mode 100644
index 000000000..2a39b6a8a
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/autoloader6.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/mortar1.wav b/sound/acf_extra/tankfx/gnomefather/mortar1.wav
new file mode 100644
index 000000000..36eaf0103
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/mortar1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/mortar2.wav b/sound/acf_extra/tankfx/gnomefather/mortar2.wav
new file mode 100644
index 000000000..00d375382
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/mortar2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/mortar3.wav b/sound/acf_extra/tankfx/gnomefather/mortar3.wav
new file mode 100644
index 000000000..cedbc8911
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/mortar3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/rack.wav b/sound/acf_extra/tankfx/gnomefather/rack.wav
new file mode 100644
index 000000000..ebcfb2ab8
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/rack.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload1.wav b/sound/acf_extra/tankfx/gnomefather/reload1.wav
new file mode 100644
index 000000000..9c936de7d
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload1.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload10.wav b/sound/acf_extra/tankfx/gnomefather/reload10.wav
new file mode 100644
index 000000000..c6167f6b3
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload10.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload11.wav b/sound/acf_extra/tankfx/gnomefather/reload11.wav
new file mode 100644
index 000000000..a4fa5844b
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload11.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload12.wav b/sound/acf_extra/tankfx/gnomefather/reload12.wav
new file mode 100644
index 000000000..047f5e2ea
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload12.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload13.wav b/sound/acf_extra/tankfx/gnomefather/reload13.wav
new file mode 100644
index 000000000..7255c6282
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload13.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload14.wav b/sound/acf_extra/tankfx/gnomefather/reload14.wav
new file mode 100644
index 000000000..8db8f5b81
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload14.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload2.wav b/sound/acf_extra/tankfx/gnomefather/reload2.wav
new file mode 100644
index 000000000..9c936de7d
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload2.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload3.wav b/sound/acf_extra/tankfx/gnomefather/reload3.wav
new file mode 100644
index 000000000..ac28d7821
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload3.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload4.wav b/sound/acf_extra/tankfx/gnomefather/reload4.wav
new file mode 100644
index 000000000..e0e9140be
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload4.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload5.wav b/sound/acf_extra/tankfx/gnomefather/reload5.wav
new file mode 100644
index 000000000..20f0fb432
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload5.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload6.wav b/sound/acf_extra/tankfx/gnomefather/reload6.wav
new file mode 100644
index 000000000..9816b2cd6
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload6.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload7.wav b/sound/acf_extra/tankfx/gnomefather/reload7.wav
new file mode 100644
index 000000000..0c2976003
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload7.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload8.wav b/sound/acf_extra/tankfx/gnomefather/reload8.wav
new file mode 100644
index 000000000..af94652df
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload8.wav differ
diff --git a/sound/acf_extra/tankfx/gnomefather/reload9.wav b/sound/acf_extra/tankfx/gnomefather/reload9.wav
new file mode 100644
index 000000000..bf3f95dd2
Binary files /dev/null and b/sound/acf_extra/tankfx/gnomefather/reload9.wav differ
diff --git a/sound/acf_extra/tankfx/grasstread.wav b/sound/acf_extra/tankfx/grasstread.wav
new file mode 100644
index 000000000..2ef9c54bf
Binary files /dev/null and b/sound/acf_extra/tankfx/grasstread.wav differ
diff --git a/sound/acf_extra/tankfx/guns/100mm.wav b/sound/acf_extra/tankfx/guns/100mm.wav
new file mode 100644
index 000000000..1313b8ea2
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/100mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/105mmhowitzer.wav b/sound/acf_extra/tankfx/guns/105mmhowitzer.wav
new file mode 100644
index 000000000..e2ece2bcc
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/105mmhowitzer.wav differ
diff --git a/sound/acf_extra/tankfx/guns/120mm.wav b/sound/acf_extra/tankfx/guns/120mm.wav
new file mode 100644
index 000000000..3eb16c617
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/120mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/155mm.wav b/sound/acf_extra/tankfx/guns/155mm.wav
new file mode 100644
index 000000000..57635ec07
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/155mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/20mm_01.wav b/sound/acf_extra/tankfx/guns/20mm_01.wav
new file mode 100644
index 000000000..b2b781fc2
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/20mm_01.wav differ
diff --git a/sound/acf_extra/tankfx/guns/20mm_02.wav b/sound/acf_extra/tankfx/guns/20mm_02.wav
new file mode 100644
index 000000000..fb4b18073
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/20mm_02.wav differ
diff --git a/sound/acf_extra/tankfx/guns/20mm_03.wav b/sound/acf_extra/tankfx/guns/20mm_03.wav
new file mode 100644
index 000000000..4aedf29a7
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/20mm_03.wav differ
diff --git a/sound/acf_extra/tankfx/guns/20mm_04.wav b/sound/acf_extra/tankfx/guns/20mm_04.wav
new file mode 100644
index 000000000..106d805f9
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/20mm_04.wav differ
diff --git a/sound/acf_extra/tankfx/guns/20mm_05.wav b/sound/acf_extra/tankfx/guns/20mm_05.wav
new file mode 100644
index 000000000..4c56e92d2
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/20mm_05.wav differ
diff --git a/sound/acf_extra/tankfx/guns/230mm.wav b/sound/acf_extra/tankfx/guns/230mm.wav
new file mode 100644
index 000000000..393b3ecf0
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/230mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/30mm.wav b/sound/acf_extra/tankfx/guns/30mm.wav
new file mode 100644
index 000000000..c1c389faa
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/30mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/50mm.wav b/sound/acf_extra/tankfx/guns/50mm.wav
new file mode 100644
index 000000000..b1140b36e
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/50mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/75mm.wav b/sound/acf_extra/tankfx/guns/75mm.wav
new file mode 100644
index 000000000..602012394
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/75mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/85mm.wav b/sound/acf_extra/tankfx/guns/85mm.wav
new file mode 100644
index 000000000..fdff87d19
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/85mm.wav differ
diff --git a/sound/acf_extra/tankfx/guns/arty_fire.wav b/sound/acf_extra/tankfx/guns/arty_fire.wav
new file mode 100644
index 000000000..3f7e95c20
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/arty_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/cannon.wav b/sound/acf_extra/tankfx/guns/cannon.wav
new file mode 100644
index 000000000..028e25f54
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/cannon.wav differ
diff --git a/sound/acf_extra/tankfx/guns/exp_aagun.wav b/sound/acf_extra/tankfx/guns/exp_aagun.wav
new file mode 100644
index 000000000..fd6708c02
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/exp_aagun.wav differ
diff --git a/sound/acf_extra/tankfx/guns/fittycal.wav b/sound/acf_extra/tankfx/guns/fittycal.wav
new file mode 100644
index 000000000..387e1effb
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/fittycal.wav differ
diff --git a/sound/acf_extra/tankfx/guns/gdi_apc_fire.wav b/sound/acf_extra/tankfx/guns/gdi_apc_fire.wav
new file mode 100644
index 000000000..6f7d847c7
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/gdi_apc_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/law_fire.wav b/sound/acf_extra/tankfx/guns/law_fire.wav
new file mode 100644
index 000000000..86e1b19c1
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/law_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/m60_fire2.wav b/sound/acf_extra/tankfx/guns/m60_fire2.wav
new file mode 100644
index 000000000..26f6f6b25
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/m60_fire2.wav differ
diff --git a/sound/acf_extra/tankfx/guns/m60_fire_1.wav b/sound/acf_extra/tankfx/guns/m60_fire_1.wav
new file mode 100644
index 000000000..77f62edcb
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/m60_fire_1.wav differ
diff --git a/sound/acf_extra/tankfx/guns/mg.wav b/sound/acf_extra/tankfx/guns/mg.wav
new file mode 100644
index 000000000..bf8c72766
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/mg.wav differ
diff --git a/sound/acf_extra/tankfx/guns/pboxhind.wav b/sound/acf_extra/tankfx/guns/pboxhind.wav
new file mode 100644
index 000000000..18e3bf322
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/pboxhind.wav differ
diff --git a/sound/acf_extra/tankfx/guns/ra_bgun.wav b/sound/acf_extra/tankfx/guns/ra_bgun.wav
new file mode 100644
index 000000000..bfd1e0941
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/ra_bgun.wav differ
diff --git a/sound/acf_extra/tankfx/guns/rangerfire.wav b/sound/acf_extra/tankfx/guns/rangerfire.wav
new file mode 100644
index 000000000..d6186ee65
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/rangerfire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/s_mammothtank_fire.wav b/sound/acf_extra/tankfx/guns/s_mammothtank_fire.wav
new file mode 100644
index 000000000..fa66eb1c3
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/s_mammothtank_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/s_med_tank_fire.wav b/sound/acf_extra/tankfx/guns/s_med_tank_fire.wav
new file mode 100644
index 000000000..aba4dec16
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/s_med_tank_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/sub_fire.wav b/sound/acf_extra/tankfx/guns/sub_fire.wav
new file mode 100644
index 000000000..82736b252
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/sub_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tailgun_fire.wav b/sound/acf_extra/tankfx/guns/tailgun_fire.wav
new file mode 100644
index 000000000..0131ab7a1
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tailgun_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tank_fire.wav b/sound/acf_extra/tankfx/guns/tank_fire.wav
new file mode 100644
index 000000000..5ec3f24b4
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tank_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tank_flame_fire.wav b/sound/acf_extra/tankfx/guns/tank_flame_fire.wav
new file mode 100644
index 000000000..5f2feb80c
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tank_flame_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tank_flameshoot_loop_1.wav b/sound/acf_extra/tankfx/guns/tank_flameshoot_loop_1.wav
new file mode 100644
index 000000000..20f1a8136
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tank_flameshoot_loop_1.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tank_light_fire.wav b/sound/acf_extra/tankfx/guns/tank_light_fire.wav
new file mode 100644
index 000000000..0ca82ba47
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tank_light_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tank_mammoth_fire.wav b/sound/acf_extra/tankfx/guns/tank_mammoth_fire.wav
new file mode 100644
index 000000000..45b4e6e0d
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tank_mammoth_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tank_medium_fire.wav b/sound/acf_extra/tankfx/guns/tank_medium_fire.wav
new file mode 100644
index 000000000..f78c5cb69
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tank_medium_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/tank_stealth_fire.wav b/sound/acf_extra/tankfx/guns/tank_stealth_fire.wav
new file mode 100644
index 000000000..7e66263a1
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/tank_stealth_fire.wav differ
diff --git a/sound/acf_extra/tankfx/guns/turretfire.wav b/sound/acf_extra/tankfx/guns/turretfire.wav
new file mode 100644
index 000000000..c74a775e0
Binary files /dev/null and b/sound/acf_extra/tankfx/guns/turretfire.wav differ
diff --git a/sound/acf_extra/tankfx/heavy_tracks.wav b/sound/acf_extra/tankfx/heavy_tracks.wav
new file mode 100644
index 000000000..4e4b746f3
Binary files /dev/null and b/sound/acf_extra/tankfx/heavy_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/icetread.wav b/sound/acf_extra/tankfx/icetread.wav
new file mode 100644
index 000000000..d4f89b889
Binary files /dev/null and b/sound/acf_extra/tankfx/icetread.wav differ
diff --git a/sound/acf_extra/tankfx/leopard_tracks.wav b/sound/acf_extra/tankfx/leopard_tracks.wav
new file mode 100644
index 000000000..07b362590
Binary files /dev/null and b/sound/acf_extra/tankfx/leopard_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/marder_tracks.wav b/sound/acf_extra/tankfx/marder_tracks.wav
new file mode 100644
index 000000000..385f50a2f
Binary files /dev/null and b/sound/acf_extra/tankfx/marder_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/medtankloop1.wav b/sound/acf_extra/tankfx/medtankloop1.wav
new file mode 100644
index 000000000..40d367cc7
Binary files /dev/null and b/sound/acf_extra/tankfx/medtankloop1.wav differ
diff --git a/sound/acf_extra/tankfx/metaltread.wav b/sound/acf_extra/tankfx/metaltread.wav
new file mode 100644
index 000000000..5678e49f0
Binary files /dev/null and b/sound/acf_extra/tankfx/metaltread.wav differ
diff --git a/sound/acf_extra/tankfx/mgreload.wav b/sound/acf_extra/tankfx/mgreload.wav
new file mode 100644
index 000000000..0a27a72de
Binary files /dev/null and b/sound/acf_extra/tankfx/mgreload.wav differ
diff --git a/sound/acf_extra/tankfx/mudtread.wav b/sound/acf_extra/tankfx/mudtread.wav
new file mode 100644
index 000000000..d66c9a252
Binary files /dev/null and b/sound/acf_extra/tankfx/mudtread.wav differ
diff --git a/sound/acf_extra/tankfx/nod_apc_hatch.wav b/sound/acf_extra/tankfx/nod_apc_hatch.wav
new file mode 100644
index 000000000..baad78e4e
Binary files /dev/null and b/sound/acf_extra/tankfx/nod_apc_hatch.wav differ
diff --git a/sound/acf_extra/tankfx/reload.wav b/sound/acf_extra/tankfx/reload.wav
new file mode 100644
index 000000000..6fbe7bd32
Binary files /dev/null and b/sound/acf_extra/tankfx/reload.wav differ
diff --git a/sound/acf_extra/tankfx/resupply_loop.wav b/sound/acf_extra/tankfx/resupply_loop.wav
new file mode 100644
index 000000000..842b15b05
Binary files /dev/null and b/sound/acf_extra/tankfx/resupply_loop.wav differ
diff --git a/sound/acf_extra/tankfx/resupply_single.wav b/sound/acf_extra/tankfx/resupply_single.wav
new file mode 100644
index 000000000..f712dab7b
Binary files /dev/null and b/sound/acf_extra/tankfx/resupply_single.wav differ
diff --git a/sound/acf_extra/tankfx/s_arty_reload.wav b/sound/acf_extra/tankfx/s_arty_reload.wav
new file mode 100644
index 000000000..330f8286b
Binary files /dev/null and b/sound/acf_extra/tankfx/s_arty_reload.wav differ
diff --git a/sound/acf_extra/tankfx/s_med_tank_reload.wav b/sound/acf_extra/tankfx/s_med_tank_reload.wav
new file mode 100644
index 000000000..5e649e1ad
Binary files /dev/null and b/sound/acf_extra/tankfx/s_med_tank_reload.wav differ
diff --git a/sound/acf_extra/tankfx/sandtread.wav b/sound/acf_extra/tankfx/sandtread.wav
new file mode 100644
index 000000000..d01d6fbc7
Binary files /dev/null and b/sound/acf_extra/tankfx/sandtread.wav differ
diff --git a/sound/acf_extra/tankfx/servo_1.wav b/sound/acf_extra/tankfx/servo_1.wav
new file mode 100644
index 000000000..dc344e6d1
Binary files /dev/null and b/sound/acf_extra/tankfx/servo_1.wav differ
diff --git a/sound/acf_extra/tankfx/servo_2.wav b/sound/acf_extra/tankfx/servo_2.wav
new file mode 100644
index 000000000..56afab2ff
Binary files /dev/null and b/sound/acf_extra/tankfx/servo_2.wav differ
diff --git a/sound/acf_extra/tankfx/shilka_tracks.wav b/sound/acf_extra/tankfx/shilka_tracks.wav
new file mode 100644
index 000000000..b7e66f2c8
Binary files /dev/null and b/sound/acf_extra/tankfx/shilka_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/start.wav b/sound/acf_extra/tankfx/start.wav
new file mode 100644
index 000000000..3f0d59f8f
Binary files /dev/null and b/sound/acf_extra/tankfx/start.wav differ
diff --git a/sound/acf_extra/tankfx/t55_tracks.wav b/sound/acf_extra/tankfx/t55_tracks.wav
new file mode 100644
index 000000000..81f2af6b9
Binary files /dev/null and b/sound/acf_extra/tankfx/t55_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/tank_bounce.wav b/sound/acf_extra/tankfx/tank_bounce.wav
new file mode 100644
index 000000000..e14b58647
Binary files /dev/null and b/sound/acf_extra/tankfx/tank_bounce.wav differ
diff --git a/sound/acf_extra/tankfx/tank_mammoth_reload.wav b/sound/acf_extra/tankfx/tank_mammoth_reload.wav
new file mode 100644
index 000000000..11db9b808
Binary files /dev/null and b/sound/acf_extra/tankfx/tank_mammoth_reload.wav differ
diff --git a/sound/acf_extra/tankfx/tank_medium_reload.wav b/sound/acf_extra/tankfx/tank_medium_reload.wav
new file mode 100644
index 000000000..576da0227
Binary files /dev/null and b/sound/acf_extra/tankfx/tank_medium_reload.wav differ
diff --git a/sound/acf_extra/tankfx/tank_move.wav b/sound/acf_extra/tankfx/tank_move.wav
new file mode 100644
index 000000000..dd65a9fa1
Binary files /dev/null and b/sound/acf_extra/tankfx/tank_move.wav differ
diff --git a/sound/acf_extra/tankfx/tankinside1.wav b/sound/acf_extra/tankfx/tankinside1.wav
new file mode 100644
index 000000000..6ba1fbdd4
Binary files /dev/null and b/sound/acf_extra/tankfx/tankinside1.wav differ
diff --git a/sound/acf_extra/tankfx/tankinside2.wav b/sound/acf_extra/tankfx/tankinside2.wav
new file mode 100644
index 000000000..6af5400e1
Binary files /dev/null and b/sound/acf_extra/tankfx/tankinside2.wav differ
diff --git a/sound/acf_extra/tankfx/tankinside3.wav b/sound/acf_extra/tankfx/tankinside3.wav
new file mode 100644
index 000000000..2687a9264
Binary files /dev/null and b/sound/acf_extra/tankfx/tankinside3.wav differ
diff --git a/sound/acf_extra/tankfx/tankinside4.wav b/sound/acf_extra/tankfx/tankinside4.wav
new file mode 100644
index 000000000..255017cc0
Binary files /dev/null and b/sound/acf_extra/tankfx/tankinside4.wav differ
diff --git a/sound/acf_extra/tankfx/tiberiumtread.wav b/sound/acf_extra/tankfx/tiberiumtread.wav
new file mode 100644
index 000000000..3b9fac09b
Binary files /dev/null and b/sound/acf_extra/tankfx/tiberiumtread.wav differ
diff --git a/sound/acf_extra/tankfx/tiger_tracks.wav b/sound/acf_extra/tankfx/tiger_tracks.wav
new file mode 100644
index 000000000..b7a489bbc
Binary files /dev/null and b/sound/acf_extra/tankfx/tiger_tracks.wav differ
diff --git a/sound/acf_extra/tankfx/tracks1.wav b/sound/acf_extra/tankfx/tracks1.wav
new file mode 100644
index 000000000..e69494b1e
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks1.wav differ
diff --git a/sound/acf_extra/tankfx/tracks2.wav b/sound/acf_extra/tankfx/tracks2.wav
new file mode 100644
index 000000000..a65a1b7f2
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks2.wav differ
diff --git a/sound/acf_extra/tankfx/tracks3.wav b/sound/acf_extra/tankfx/tracks3.wav
new file mode 100644
index 000000000..ef6672da0
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks3.wav differ
diff --git a/sound/acf_extra/tankfx/tracks4.wav b/sound/acf_extra/tankfx/tracks4.wav
new file mode 100644
index 000000000..dd5054f50
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks4.wav differ
diff --git a/sound/acf_extra/tankfx/tracks5.wav b/sound/acf_extra/tankfx/tracks5.wav
new file mode 100644
index 000000000..52a735334
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks5.wav differ
diff --git a/sound/acf_extra/tankfx/tracks6.wav b/sound/acf_extra/tankfx/tracks6.wav
new file mode 100644
index 000000000..8bd582966
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks6.wav differ
diff --git a/sound/acf_extra/tankfx/tracks7.wav b/sound/acf_extra/tankfx/tracks7.wav
new file mode 100644
index 000000000..10db716b7
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks7.wav differ
diff --git a/sound/acf_extra/tankfx/tracks8.wav b/sound/acf_extra/tankfx/tracks8.wav
new file mode 100644
index 000000000..8ccda09c3
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks8.wav differ
diff --git a/sound/acf_extra/tankfx/tracks9.wav b/sound/acf_extra/tankfx/tracks9.wav
new file mode 100644
index 000000000..0fcc3292e
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks9.wav differ
diff --git a/sound/acf_extra/tankfx/tracks_composite.wav b/sound/acf_extra/tankfx/tracks_composite.wav
new file mode 100644
index 000000000..872c1a8d6
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks_composite.wav differ
diff --git a/sound/acf_extra/tankfx/tracks_rubber.wav b/sound/acf_extra/tankfx/tracks_rubber.wav
new file mode 100644
index 000000000..20c36994b
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks_rubber.wav differ
diff --git a/sound/acf_extra/tankfx/tracks_steel.wav b/sound/acf_extra/tankfx/tracks_steel.wav
new file mode 100644
index 000000000..884b866d5
Binary files /dev/null and b/sound/acf_extra/tankfx/tracks_steel.wav differ
diff --git a/sound/acf_extra/tankfx/treadsheavy.wav b/sound/acf_extra/tankfx/treadsheavy.wav
new file mode 100644
index 000000000..413b4efaf
Binary files /dev/null and b/sound/acf_extra/tankfx/treadsheavy.wav differ
diff --git a/sound/acf_extra/tankfx/treadslight.wav b/sound/acf_extra/tankfx/treadslight.wav
new file mode 100644
index 000000000..66ecddb21
Binary files /dev/null and b/sound/acf_extra/tankfx/treadslight.wav differ
diff --git a/sound/acf_extra/tankfx/treadsmedium.wav b/sound/acf_extra/tankfx/treadsmedium.wav
new file mode 100644
index 000000000..5c326e712
Binary files /dev/null and b/sound/acf_extra/tankfx/treadsmedium.wav differ
diff --git a/sound/acf_extra/tankfx/turret.wav b/sound/acf_extra/tankfx/turret.wav
new file mode 100644
index 000000000..f094f375c
Binary files /dev/null and b/sound/acf_extra/tankfx/turret.wav differ
diff --git a/sound/acf_extra/tankfx/turret2.wav b/sound/acf_extra/tankfx/turret2.wav
new file mode 100644
index 000000000..9192cc83a
Binary files /dev/null and b/sound/acf_extra/tankfx/turret2.wav differ
diff --git a/sound/acf_extra/tankfx/turret3.wav b/sound/acf_extra/tankfx/turret3.wav
new file mode 100644
index 000000000..6efb8f0b4
Binary files /dev/null and b/sound/acf_extra/tankfx/turret3.wav differ
diff --git a/sound/acf_extra/tankfx/turret4.wav b/sound/acf_extra/tankfx/turret4.wav
new file mode 100644
index 000000000..c3af05318
Binary files /dev/null and b/sound/acf_extra/tankfx/turret4.wav differ
diff --git a/sound/acf_extra/tankfx/turret5.wav b/sound/acf_extra/tankfx/turret5.wav
new file mode 100644
index 000000000..1d0586ad2
Binary files /dev/null and b/sound/acf_extra/tankfx/turret5.wav differ
diff --git a/sound/acf_extra/tankfx/turretelectric.wav b/sound/acf_extra/tankfx/turretelectric.wav
new file mode 100644
index 000000000..e4295b7ce
Binary files /dev/null and b/sound/acf_extra/tankfx/turretelectric.wav differ
diff --git a/sound/acf_extra/tankfx/turretelectric2.wav b/sound/acf_extra/tankfx/turretelectric2.wav
new file mode 100644
index 000000000..d15879377
Binary files /dev/null and b/sound/acf_extra/tankfx/turretelectric2.wav differ
diff --git a/sound/acf_extra/tankfx/woodtread.wav b/sound/acf_extra/tankfx/woodtread.wav
new file mode 100644
index 000000000..805a575ea
Binary files /dev/null and b/sound/acf_extra/tankfx/woodtread.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/evo8_blowoff.wav b/sound/acf_extra/vehiclefx/boost/evo8_blowoff.wav
new file mode 100644
index 000000000..31ff434e8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/evo8_blowoff.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/gear_change_dump1.wav b/sound/acf_extra/vehiclefx/boost/gear_change_dump1.wav
new file mode 100644
index 000000000..1fffb2260
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/gear_change_dump1.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/hiss.wav b/sound/acf_extra/vehiclefx/boost/hiss.wav
new file mode 100644
index 000000000..d8a476459
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/hiss.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/supercharger.wav b/sound/acf_extra/vehiclefx/boost/supercharger.wav
new file mode 100644
index 000000000..2eea5646f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/supercharger.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/tcl_turbo.wav b/sound/acf_extra/vehiclefx/boost/tcl_turbo.wav
new file mode 100644
index 000000000..2e3fca5b4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/tcl_turbo.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo1.wav b/sound/acf_extra/vehiclefx/boost/turbo1.wav
new file mode 100644
index 000000000..e2345a5c7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo1.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_hiss1.wav b/sound/acf_extra/vehiclefx/boost/turbo_hiss1.wav
new file mode 100644
index 000000000..0eafce452
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_hiss1.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_hiss2.wav b/sound/acf_extra/vehiclefx/boost/turbo_hiss2.wav
new file mode 100644
index 000000000..62b8d7a90
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_hiss2.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_hiss3.wav b/sound/acf_extra/vehiclefx/boost/turbo_hiss3.wav
new file mode 100644
index 000000000..e552c3cc7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_hiss3.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_hiss4.wav b/sound/acf_extra/vehiclefx/boost/turbo_hiss4.wav
new file mode 100644
index 000000000..91b9a99de
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_hiss4.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_hiss5.wav b/sound/acf_extra/vehiclefx/boost/turbo_hiss5.wav
new file mode 100644
index 000000000..4501d18d8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_hiss5.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_pop_1.wav b/sound/acf_extra/vehiclefx/boost/turbo_pop_1.wav
new file mode 100644
index 000000000..618fcb622
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_pop_1.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_pop_2.wav b/sound/acf_extra/vehiclefx/boost/turbo_pop_2.wav
new file mode 100644
index 000000000..c706b2bb1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_pop_2.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_pop_3.wav b/sound/acf_extra/vehiclefx/boost/turbo_pop_3.wav
new file mode 100644
index 000000000..61b2c8fe1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_pop_3.wav differ
diff --git a/sound/acf_extra/vehiclefx/boost/turbo_waste.wav b/sound/acf_extra/vehiclefx/boost/turbo_waste.wav
new file mode 100644
index 000000000..792c2166c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/boost/turbo_waste.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/222_move.wav b/sound/acf_extra/vehiclefx/engines/222_move.wav
new file mode 100644
index 000000000..e02a92b1f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/222_move.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/Chieftengine.wav b/sound/acf_extra/vehiclefx/engines/Chieftengine.wav
new file mode 100644
index 000000000..c91fedef2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/Chieftengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/FAAV_loop.wav b/sound/acf_extra/vehiclefx/engines/FAAV_loop.wav
new file mode 100644
index 000000000..f49e63a75
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/FAAV_loop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/FAAV_stop.wav b/sound/acf_extra/vehiclefx/engines/FAAV_stop.wav
new file mode 100644
index 000000000..90f730483
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/FAAV_stop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/HMMWV_loop.wav b/sound/acf_extra/vehiclefx/engines/HMMWV_loop.wav
new file mode 100644
index 000000000..afa6ccd0f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/HMMWV_loop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/LAV_loop.wav b/sound/acf_extra/vehiclefx/engines/LAV_loop.wav
new file mode 100644
index 000000000..b5e1da0e1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/LAV_loop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/LAV_stop.wav b/sound/acf_extra/vehiclefx/engines/LAV_stop.wav
new file mode 100644
index 000000000..28a85c158
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/LAV_stop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/Nanjing_loop.wav b/sound/acf_extra/vehiclefx/engines/Nanjing_loop.wav
new file mode 100644
index 000000000..8df803642
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/Nanjing_loop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/Nanjing_stop.wav b/sound/acf_extra/vehiclefx/engines/Nanjing_stop.wav
new file mode 100644
index 000000000..e164767ab
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/Nanjing_stop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/abrams.wav b/sound/acf_extra/vehiclefx/engines/abrams.wav
new file mode 100644
index 000000000..f07f33116
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/abrams.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/as90.wav b/sound/acf_extra/vehiclefx/engines/as90.wav
new file mode 100644
index 000000000..7998bc87f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/as90.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/bike650.wav b/sound/acf_extra/vehiclefx/engines/bike650.wav
new file mode 100644
index 000000000..0f356d2af
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/bike650.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/blank.wav b/sound/acf_extra/vehiclefx/engines/blank.wav
new file mode 100644
index 000000000..f3e7d261a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/blank.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/bmp.wav b/sound/acf_extra/vehiclefx/engines/bmp.wav
new file mode 100644
index 000000000..64446d3eb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/bmp.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/brdm.wav b/sound/acf_extra/vehiclefx/engines/brdm.wav
new file mode 100644
index 000000000..2a517db7c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/brdm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/britengine.wav b/sound/acf_extra/vehiclefx/engines/britengine.wav
new file mode 100644
index 000000000..e9b26b049
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/britengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/challenger2.wav b/sound/acf_extra/vehiclefx/engines/challenger2.wav
new file mode 100644
index 000000000..16e3868bc
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/challenger2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/challenger2_2.wav b/sound/acf_extra/vehiclefx/engines/challenger2_2.wav
new file mode 100644
index 000000000..7714d3756
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/challenger2_2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/Dodge.wav b/sound/acf_extra/vehiclefx/engines/coh/Dodge.wav
new file mode 100644
index 000000000..6b011bac1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/Dodge.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/Dodge_end.wav b/sound/acf_extra/vehiclefx/engines/coh/Dodge_end.wav
new file mode 100644
index 000000000..8aab99606
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/Dodge_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/Dodge_move.wav b/sound/acf_extra/vehiclefx/engines/coh/Dodge_move.wav
new file mode 100644
index 000000000..d4f65de63
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/Dodge_move.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/Dodge_up.wav b/sound/acf_extra/vehiclefx/engines/coh/Dodge_up.wav
new file mode 100644
index 000000000..95474dd3e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/Dodge_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/GMC.wav b/sound/acf_extra/vehiclefx/engines/coh/GMC.wav
new file mode 100644
index 000000000..6f4059d52
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/GMC.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/GMC_end.wav b/sound/acf_extra/vehiclefx/engines/coh/GMC_end.wav
new file mode 100644
index 000000000..76a4770a8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/GMC_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/GMC_up.wav b/sound/acf_extra/vehiclefx/engines/coh/GMC_up.wav
new file mode 100644
index 000000000..d07a408a2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/GMC_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/ba11.wav b/sound/acf_extra/vehiclefx/engines/coh/ba11.wav
new file mode 100644
index 000000000..f6e83563a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/ba11.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/ba11_end.wav b/sound/acf_extra/vehiclefx/engines/coh/ba11_end.wav
new file mode 100644
index 000000000..82b6a76bd
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/ba11_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/ba11_up.wav b/sound/acf_extra/vehiclefx/engines/coh/ba11_up.wav
new file mode 100644
index 000000000..f94f768aa
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/ba11_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/ba20.wav b/sound/acf_extra/vehiclefx/engines/coh/ba20.wav
new file mode 100644
index 000000000..277f30546
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/ba20.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/ba20_end.wav b/sound/acf_extra/vehiclefx/engines/coh/ba20_end.wav
new file mode 100644
index 000000000..2af30725b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/ba20_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/ba20_up.wav b/sound/acf_extra/vehiclefx/engines/coh/ba20_up.wav
new file mode 100644
index 000000000..352c0c06e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/ba20_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bishop.wav b/sound/acf_extra/vehiclefx/engines/coh/bishop.wav
new file mode 100644
index 000000000..bb26f1f88
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bishop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bishop_end.wav b/sound/acf_extra/vehiclefx/engines/coh/bishop_end.wav
new file mode 100644
index 000000000..c6df26247
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bishop_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bishop_up.wav b/sound/acf_extra/vehiclefx/engines/coh/bishop_up.wav
new file mode 100644
index 000000000..1607b4dc4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bishop_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/blitz.wav b/sound/acf_extra/vehiclefx/engines/coh/blitz.wav
new file mode 100644
index 000000000..7920d37ec
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/blitz.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/blitz_end.wav b/sound/acf_extra/vehiclefx/engines/coh/blitz_end.wav
new file mode 100644
index 000000000..a31df50e2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/blitz_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/blitz_up.wav b/sound/acf_extra/vehiclefx/engines/coh/blitz_up.wav
new file mode 100644
index 000000000..c29e0c94e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/blitz_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bmw.wav b/sound/acf_extra/vehiclefx/engines/coh/bmw.wav
new file mode 100644
index 000000000..dd30d572b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bmw.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bmw_up.wav b/sound/acf_extra/vehiclefx/engines/coh/bmw_up.wav
new file mode 100644
index 000000000..819b41aa1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bmw_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bt.wav b/sound/acf_extra/vehiclefx/engines/coh/bt.wav
new file mode 100644
index 000000000..f6d582a31
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bt.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bt_end.wav b/sound/acf_extra/vehiclefx/engines/coh/bt_end.wav
new file mode 100644
index 000000000..43dca5571
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bt_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/bt_up.wav b/sound/acf_extra/vehiclefx/engines/coh/bt_up.wav
new file mode 100644
index 000000000..a56e8505e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/bt_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/car.wav b/sound/acf_extra/vehiclefx/engines/coh/car.wav
new file mode 100644
index 000000000..3b61a8edb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/car.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/car_end.wav b/sound/acf_extra/vehiclefx/engines/coh/car_end.wav
new file mode 100644
index 000000000..c7f9fa3ae
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/car_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/car_up.wav b/sound/acf_extra/vehiclefx/engines/coh/car_up.wav
new file mode 100644
index 000000000..f4fb9dbe1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/car_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/chi-ha.wav b/sound/acf_extra/vehiclefx/engines/coh/chi-ha.wav
new file mode 100644
index 000000000..f9ebff806
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/chi-ha.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/churchill.wav b/sound/acf_extra/vehiclefx/engines/coh/churchill.wav
new file mode 100644
index 000000000..7e9ef5152
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/churchill.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/churchill_end.wav b/sound/acf_extra/vehiclefx/engines/coh/churchill_end.wav
new file mode 100644
index 000000000..33540bc9b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/churchill_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/churchill_up.wav b/sound/acf_extra/vehiclefx/engines/coh/churchill_up.wav
new file mode 100644
index 000000000..ef8c42560
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/churchill_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/cromwell.wav b/sound/acf_extra/vehiclefx/engines/coh/cromwell.wav
new file mode 100644
index 000000000..fc4916329
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/cromwell.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/cromwell_end.wav b/sound/acf_extra/vehiclefx/engines/coh/cromwell_end.wav
new file mode 100644
index 000000000..e9480ddfe
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/cromwell_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/cromwell_up.wav b/sound/acf_extra/vehiclefx/engines/coh/cromwell_up.wav
new file mode 100644
index 000000000..bb8e3fe1a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/cromwell_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/crusader.wav b/sound/acf_extra/vehiclefx/engines/coh/crusader.wav
new file mode 100644
index 000000000..a538caf66
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/crusader.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/crusader_end.wav b/sound/acf_extra/vehiclefx/engines/coh/crusader_end.wav
new file mode 100644
index 000000000..471d97284
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/crusader_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/crusader_up.wav b/sound/acf_extra/vehiclefx/engines/coh/crusader_up.wav
new file mode 100644
index 000000000..0b56e30a6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/crusader_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/dodge_move_new.wav b/sound/acf_extra/vehiclefx/engines/coh/dodge_move_new.wav
new file mode 100644
index 000000000..b760d017f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/dodge_move_new.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/dodge_start.wav b/sound/acf_extra/vehiclefx/engines/coh/dodge_start.wav
new file mode 100644
index 000000000..cf0d3b902
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/dodge_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/door.wav b/sound/acf_extra/vehiclefx/engines/coh/door.wav
new file mode 100644
index 000000000..52adf10f3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/door.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/ferry.wav b/sound/acf_extra/vehiclefx/engines/coh/ferry.wav
new file mode 100644
index 000000000..87fe5ed2f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/ferry.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/folder.set b/sound/acf_extra/vehiclefx/engines/coh/folder.set
new file mode 100644
index 000000000..9ecfd09cd
--- /dev/null
+++ b/sound/acf_extra/vehiclefx/engines/coh/folder.set
@@ -0,0 +1,3 @@
+{sound
+ {signal movement 25}
+}
\ No newline at end of file
diff --git a/sound/acf_extra/vehiclefx/engines/coh/heavy.wav b/sound/acf_extra/vehiclefx/engines/coh/heavy.wav
new file mode 100644
index 000000000..a1d9e8431
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/heavy.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/heavy_end.wav b/sound/acf_extra/vehiclefx/engines/coh/heavy_end.wav
new file mode 100644
index 000000000..288ec6503
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/heavy_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/heavy_up.wav b/sound/acf_extra/vehiclefx/engines/coh/heavy_up.wav
new file mode 100644
index 000000000..c22a7f079
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/heavy_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/hetzer.wav b/sound/acf_extra/vehiclefx/engines/coh/hetzer.wav
new file mode 100644
index 000000000..261793586
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/hetzer.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/hetzer_end.wav b/sound/acf_extra/vehiclefx/engines/coh/hetzer_end.wav
new file mode 100644
index 000000000..15dae6112
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/hetzer_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/hetzer_up.wav b/sound/acf_extra/vehiclefx/engines/coh/hetzer_up.wav
new file mode 100644
index 000000000..76e8b8d8e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/hetzer_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/horch.wav b/sound/acf_extra/vehiclefx/engines/coh/horch.wav
new file mode 100644
index 000000000..2256e9871
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/horch.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/horch_end.wav b/sound/acf_extra/vehiclefx/engines/coh/horch_end.wav
new file mode 100644
index 000000000..19cb56a85
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/horch_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/horch_up.wav b/sound/acf_extra/vehiclefx/engines/coh/horch_up.wav
new file mode 100644
index 000000000..c10aeb95c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/horch_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/is.wav b/sound/acf_extra/vehiclefx/engines/coh/is.wav
new file mode 100644
index 000000000..3e8871251
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/is.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/is_end.wav b/sound/acf_extra/vehiclefx/engines/coh/is_end.wav
new file mode 100644
index 000000000..562dadb16
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/is_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/is_up.wav b/sound/acf_extra/vehiclefx/engines/coh/is_up.wav
new file mode 100644
index 000000000..144790d67
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/is_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/isu.wav b/sound/acf_extra/vehiclefx/engines/coh/isu.wav
new file mode 100644
index 000000000..b6efcf7d8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/isu.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/isu_end.wav b/sound/acf_extra/vehiclefx/engines/coh/isu_end.wav
new file mode 100644
index 000000000..72d6e79f2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/isu_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/isu_up.wav b/sound/acf_extra/vehiclefx/engines/coh/isu_up.wav
new file mode 100644
index 000000000..c2f1d0f09
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/isu_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/jagdtiger.wav b/sound/acf_extra/vehiclefx/engines/coh/jagdtiger.wav
new file mode 100644
index 000000000..5110439eb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/jagdtiger.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/jagdtiger_end.wav b/sound/acf_extra/vehiclefx/engines/coh/jagdtiger_end.wav
new file mode 100644
index 000000000..b554341da
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/jagdtiger_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/jugdpanther.wav b/sound/acf_extra/vehiclefx/engines/coh/jugdpanther.wav
new file mode 100644
index 000000000..20da652a8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/jugdpanther.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/jugdpanther_end.wav b/sound/acf_extra/vehiclefx/engines/coh/jugdpanther_end.wav
new file mode 100644
index 000000000..58492372b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/jugdpanther_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/jugdpanther_up.wav b/sound/acf_extra/vehiclefx/engines/coh/jugdpanther_up.wav
new file mode 100644
index 000000000..0d3c302d1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/jugdpanther_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/kubel.wav b/sound/acf_extra/vehiclefx/engines/coh/kubel.wav
new file mode 100644
index 000000000..0239314d6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/kubel.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/kubel_end.wav b/sound/acf_extra/vehiclefx/engines/coh/kubel_end.wav
new file mode 100644
index 000000000..60ee38eef
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/kubel_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/kubel_up.wav b/sound/acf_extra/vehiclefx/engines/coh/kubel_up.wav
new file mode 100644
index 000000000..7c47fcc11
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/kubel_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/kv.wav b/sound/acf_extra/vehiclefx/engines/coh/kv.wav
new file mode 100644
index 000000000..3f96148ce
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/kv.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/kv_end.wav b/sound/acf_extra/vehiclefx/engines/coh/kv_end.wav
new file mode 100644
index 000000000..cfcf7d7cb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/kv_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/kv_up.wav b/sound/acf_extra/vehiclefx/engines/coh/kv_up.wav
new file mode 100644
index 000000000..a0fea59c0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/kv_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m10wolverine.wav b/sound/acf_extra/vehiclefx/engines/coh/m10wolverine.wav
new file mode 100644
index 000000000..de5a82332
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m10wolverine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m18hellcat.wav b/sound/acf_extra/vehiclefx/engines/coh/m18hellcat.wav
new file mode 100644
index 000000000..0cfac0fb8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m18hellcat.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m26.wav b/sound/acf_extra/vehiclefx/engines/coh/m26.wav
new file mode 100644
index 000000000..2c3daeec8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m26.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m3a1.wav b/sound/acf_extra/vehiclefx/engines/coh/m3a1.wav
new file mode 100644
index 000000000..1171d1dc2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m3a1.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m3a1_end.wav b/sound/acf_extra/vehiclefx/engines/coh/m3a1_end.wav
new file mode 100644
index 000000000..ad2c68a55
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m3a1_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m3a1_up.wav b/sound/acf_extra/vehiclefx/engines/coh/m3a1_up.wav
new file mode 100644
index 000000000..3f253e08b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m3a1_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m3stuart.wav b/sound/acf_extra/vehiclefx/engines/coh/m3stuart.wav
new file mode 100644
index 000000000..fbffd35d7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m3stuart.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m4.wav b/sound/acf_extra/vehiclefx/engines/coh/m4.wav
new file mode 100644
index 000000000..dbfcaac91
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m4.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m4_end.wav b/sound/acf_extra/vehiclefx/engines/coh/m4_end.wav
new file mode 100644
index 000000000..80828b5bd
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m4_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m4_up.wav b/sound/acf_extra/vehiclefx/engines/coh/m4_up.wav
new file mode 100644
index 000000000..82f51bbc6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m4_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m4a2.wav b/sound/acf_extra/vehiclefx/engines/coh/m4a2.wav
new file mode 100644
index 000000000..fcdc6b8d5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m4a2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m4a2_end.wav b/sound/acf_extra/vehiclefx/engines/coh/m4a2_end.wav
new file mode 100644
index 000000000..13ae80a1e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m4a2_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m4a2_up.wav b/sound/acf_extra/vehiclefx/engines/coh/m4a2_up.wav
new file mode 100644
index 000000000..61466d077
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m4a2_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m7.wav b/sound/acf_extra/vehiclefx/engines/coh/m7.wav
new file mode 100644
index 000000000..97c87722c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m7.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m7_end.wav b/sound/acf_extra/vehiclefx/engines/coh/m7_end.wav
new file mode 100644
index 000000000..c3a3d5c98
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m7_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m7_up.wav b/sound/acf_extra/vehiclefx/engines/coh/m7_up.wav
new file mode 100644
index 000000000..cee5a1f7b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m7_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m8.wav b/sound/acf_extra/vehiclefx/engines/coh/m8.wav
new file mode 100644
index 000000000..c56c97e77
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m8.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m8grayhound.wav b/sound/acf_extra/vehiclefx/engines/coh/m8grayhound.wav
new file mode 100644
index 000000000..a80572266
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m8grayhound.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m8grayhound_end.wav b/sound/acf_extra/vehiclefx/engines/coh/m8grayhound_end.wav
new file mode 100644
index 000000000..42cdccf36
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m8grayhound_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/m8grayhound_up.wav b/sound/acf_extra/vehiclefx/engines/coh/m8grayhound_up.wav
new file mode 100644
index 000000000..3b093e927
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/m8grayhound_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/mb.wav b/sound/acf_extra/vehiclefx/engines/coh/mb.wav
new file mode 100644
index 000000000..4a66fbd9e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/mb.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/mb_end.wav b/sound/acf_extra/vehiclefx/engines/coh/mb_end.wav
new file mode 100644
index 000000000..b6e6da842
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/mb_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/mb_up.wav b/sound/acf_extra/vehiclefx/engines/coh/mb_up.wav
new file mode 100644
index 000000000..2847b2c37
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/mb_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/mk7.wav b/sound/acf_extra/vehiclefx/engines/coh/mk7.wav
new file mode 100644
index 000000000..ad1675cc3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/mk7.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/mk7_end.wav b/sound/acf_extra/vehiclefx/engines/coh/mk7_end.wav
new file mode 100644
index 000000000..d8b3051dd
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/mk7_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/mk7_up.wav b/sound/acf_extra/vehiclefx/engines/coh/mk7_up.wav
new file mode 100644
index 000000000..0931676e0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/mk7_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/moto_end.wav b/sound/acf_extra/vehiclefx/engines/coh/moto_end.wav
new file mode 100644
index 000000000..76a651553
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/moto_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz1.wav b/sound/acf_extra/vehiclefx/engines/coh/pz1.wav
new file mode 100644
index 000000000..5a2119bb2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz1.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz1_end.wav b/sound/acf_extra/vehiclefx/engines/coh/pz1_end.wav
new file mode 100644
index 000000000..80740285c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz1_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz1_up.wav b/sound/acf_extra/vehiclefx/engines/coh/pz1_up.wav
new file mode 100644
index 000000000..48b2c3677
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz1_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz2.wav b/sound/acf_extra/vehiclefx/engines/coh/pz2.wav
new file mode 100644
index 000000000..b1430878e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz2_end.wav b/sound/acf_extra/vehiclefx/engines/coh/pz2_end.wav
new file mode 100644
index 000000000..374fbd0d8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz2_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz2_up.wav b/sound/acf_extra/vehiclefx/engines/coh/pz2_up.wav
new file mode 100644
index 000000000..c83e9a7cc
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz2_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz3.wav b/sound/acf_extra/vehiclefx/engines/coh/pz3.wav
new file mode 100644
index 000000000..836b977dd
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz3.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz3_end.wav b/sound/acf_extra/vehiclefx/engines/coh/pz3_end.wav
new file mode 100644
index 000000000..be9a5e4b2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz3_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz3_up.wav b/sound/acf_extra/vehiclefx/engines/coh/pz3_up.wav
new file mode 100644
index 000000000..ac15d01c0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz3_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz4.wav b/sound/acf_extra/vehiclefx/engines/coh/pz4.wav
new file mode 100644
index 000000000..0cabf60b2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz4.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz4_end.wav b/sound/acf_extra/vehiclefx/engines/coh/pz4_end.wav
new file mode 100644
index 000000000..3301e1ef1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz4_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz4_up.wav b/sound/acf_extra/vehiclefx/engines/coh/pz4_up.wav
new file mode 100644
index 000000000..31013f7e8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz4_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz6.wav b/sound/acf_extra/vehiclefx/engines/coh/pz6.wav
new file mode 100644
index 000000000..6072dddf2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz6.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz6_end.wav b/sound/acf_extra/vehiclefx/engines/coh/pz6_end.wav
new file mode 100644
index 000000000..ff40361a2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz6_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/pz6_up.wav b/sound/acf_extra/vehiclefx/engines/coh/pz6_up.wav
new file mode 100644
index 000000000..05caeb0e9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/pz6_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz10.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz10.wav
new file mode 100644
index 000000000..d61003ce8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz10.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz10_end.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz10_end.wav
new file mode 100644
index 000000000..52a9c000f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz10_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz10_up.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz10_up.wav
new file mode 100644
index 000000000..bad5c6d26
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz10_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz232.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz232.wav
new file mode 100644
index 000000000..84e51b447
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz232.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz232_end.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz232_end.wav
new file mode 100644
index 000000000..fe1157acb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz232_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz232_up.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz232_up.wav
new file mode 100644
index 000000000..31b8253ad
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz232_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz234.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz234.wav
new file mode 100644
index 000000000..7bf3206f9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz234.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz234_end.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz234_end.wav
new file mode 100644
index 000000000..ff0bcd93a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz234_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz234_up.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz234_up.wav
new file mode 100644
index 000000000..2139ae390
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz234_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz250.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz250.wav
new file mode 100644
index 000000000..30e043f12
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz250.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz250_end.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz250_end.wav
new file mode 100644
index 000000000..9a798f9c9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz250_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz250_up.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz250_up.wav
new file mode 100644
index 000000000..d26809dc4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz250_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz251.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz251.wav
new file mode 100644
index 000000000..7b3edca8f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz251.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz251_end.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz251_end.wav
new file mode 100644
index 000000000..36f37d4b0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz251_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/sdkfz251_up.wav b/sound/acf_extra/vehiclefx/engines/coh/sdkfz251_up.wav
new file mode 100644
index 000000000..118e8be27
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/sdkfz251_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/skid_dodge.wav b/sound/acf_extra/vehiclefx/engines/coh/skid_dodge.wav
new file mode 100644
index 000000000..3e09045ba
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/skid_dodge.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t-26.wav b/sound/acf_extra/vehiclefx/engines/coh/t-26.wav
new file mode 100644
index 000000000..01875e0c8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t-26.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t-26_end.wav b/sound/acf_extra/vehiclefx/engines/coh/t-26_end.wav
new file mode 100644
index 000000000..31106cace
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t-26_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t-26_up.wav b/sound/acf_extra/vehiclefx/engines/coh/t-26_up.wav
new file mode 100644
index 000000000..9c54a7f25
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t-26_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t26.wav b/sound/acf_extra/vehiclefx/engines/coh/t26.wav
new file mode 100644
index 000000000..1853815aa
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t26.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t26_end.wav b/sound/acf_extra/vehiclefx/engines/coh/t26_end.wav
new file mode 100644
index 000000000..474e05eac
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t26_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t26_up.wav b/sound/acf_extra/vehiclefx/engines/coh/t26_up.wav
new file mode 100644
index 000000000..97f0dde7b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t26_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t34.wav b/sound/acf_extra/vehiclefx/engines/coh/t34.wav
new file mode 100644
index 000000000..c6ae6e16a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t34.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t3485.wav b/sound/acf_extra/vehiclefx/engines/coh/t3485.wav
new file mode 100644
index 000000000..09132dd28
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t3485.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t3485_end.wav b/sound/acf_extra/vehiclefx/engines/coh/t3485_end.wav
new file mode 100644
index 000000000..19cda06ac
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t3485_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t3485_up.wav b/sound/acf_extra/vehiclefx/engines/coh/t3485_up.wav
new file mode 100644
index 000000000..ca4011f3c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t3485_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t34_end.wav b/sound/acf_extra/vehiclefx/engines/coh/t34_end.wav
new file mode 100644
index 000000000..7435b764f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t34_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/t34_up.wav b/sound/acf_extra/vehiclefx/engines/coh/t34_up.wav
new file mode 100644
index 000000000..ca373c065
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/t34_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/tank.wav b/sound/acf_extra/vehiclefx/engines/coh/tank.wav
new file mode 100644
index 000000000..98b610906
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/tank.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/tank_end.wav b/sound/acf_extra/vehiclefx/engines/coh/tank_end.wav
new file mode 100644
index 000000000..ded615bd4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/tank_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/tank_up.wav b/sound/acf_extra/vehiclefx/engines/coh/tank_up.wav
new file mode 100644
index 000000000..8be5d7d99
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/tank_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/tankengine.wav b/sound/acf_extra/vehiclefx/engines/coh/tankengine.wav
new file mode 100644
index 000000000..e27b765ea
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/tankengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/tankengine_end.wav b/sound/acf_extra/vehiclefx/engines/coh/tankengine_end.wav
new file mode 100644
index 000000000..ded615bd4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/tankengine_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/tankengine_up.wav b/sound/acf_extra/vehiclefx/engines/coh/tankengine_up.wav
new file mode 100644
index 000000000..8be5d7d99
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/tankengine_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/train.wav b/sound/acf_extra/vehiclefx/engines/coh/train.wav
new file mode 100644
index 000000000..0a31bbaaa
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/train.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/train_end.wav b/sound/acf_extra/vehiclefx/engines/coh/train_end.wav
new file mode 100644
index 000000000..944700c87
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/train_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/train_up.wav b/sound/acf_extra/vehiclefx/engines/coh/train_up.wav
new file mode 100644
index 000000000..559030b48
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/train_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/turtoise.wav b/sound/acf_extra/vehiclefx/engines/coh/turtoise.wav
new file mode 100644
index 000000000..beea920d5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/turtoise.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/turtoise_end.wav b/sound/acf_extra/vehiclefx/engines/coh/turtoise_end.wav
new file mode 100644
index 000000000..0d02add6d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/turtoise_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/turtoise_up.wav b/sound/acf_extra/vehiclefx/engines/coh/turtoise_up.wav
new file mode 100644
index 000000000..10c9e8d0b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/turtoise_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/zis.wav b/sound/acf_extra/vehiclefx/engines/coh/zis.wav
new file mode 100644
index 000000000..931479751
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/zis.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/zis_end.wav b/sound/acf_extra/vehiclefx/engines/coh/zis_end.wav
new file mode 100644
index 000000000..74465f3df
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/zis_end.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/coh/zis_up.wav b/sound/acf_extra/vehiclefx/engines/coh/zis_up.wav
new file mode 100644
index 000000000..2a2d53489
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/coh/zis_up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/diesel/high.wav b/sound/acf_extra/vehiclefx/engines/diesel/high.wav
new file mode 100644
index 000000000..5ccbeb5c1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/diesel/high.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/diesel/newdiesel.wav b/sound/acf_extra/vehiclefx/engines/diesel/newdiesel.wav
new file mode 100644
index 000000000..bcb831730
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/diesel/newdiesel.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/dozer.wav b/sound/acf_extra/vehiclefx/engines/dozer.wav
new file mode 100644
index 000000000..a3c283b60
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/dozer.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat4/flat4.wav b/sound/acf_extra/vehiclefx/engines/flat4/flat4.wav
new file mode 100644
index 000000000..511ae0288
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat4/flat4.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat4/vw.wav b/sound/acf_extra/vehiclefx/engines/flat4/vw.wav
new file mode 100644
index 000000000..bf2e21d5c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat4/vw.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/911S_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/flat6/911S_onhigh.WAV
new file mode 100644
index 000000000..05e503470
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/911S_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/911S_onlow.WAV b/sound/acf_extra/vehiclefx/engines/flat6/911S_onlow.WAV
new file mode 100644
index 000000000..57f7901c6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/911S_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/911S_onmid.WAV b/sound/acf_extra/vehiclefx/engines/flat6/911S_onmid.WAV
new file mode 100644
index 000000000..2989a735e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/911S_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/911S_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/flat6/911S_onverylow.WAV
new file mode 100644
index 000000000..5f98bcc6a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/911S_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONHIGH4.WAV b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONHIGH4.WAV
new file mode 100644
index 000000000..57aeeefc5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONHIGH4.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONLOW2.WAV b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONLOW2.WAV
new file mode 100644
index 000000000..a42a09840
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONLOW2.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONMID8.WAV b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONMID8.WAV
new file mode 100644
index 000000000..e4092d7a6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONMID8.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONVERYLOW2.WAV b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONVERYLOW2.WAV
new file mode 100644
index 000000000..795892809
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/RSR_ONVERYLOW2.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onhigh.wav b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onhigh.wav
new file mode 100644
index 000000000..953c752d0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onlow.wav b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onlow.wav
new file mode 100644
index 000000000..67049bb98
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onmid.wav b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onmid.wav
new file mode 100644
index 000000000..927956034
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onverylow.wav b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onverylow.wav
new file mode 100644
index 000000000..46fb85b75
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/flat6/rsr28-onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/b4_med.wav b/sound/acf_extra/vehiclefx/engines/fsp/b4_med.wav
new file mode 100644
index 000000000..61f862d85
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/b4_med.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/b4_subaru_ej257.wav b/sound/acf_extra/vehiclefx/engines/fsp/b4_subaru_ej257.wav
new file mode 100644
index 000000000..3e9eb4709
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/b4_subaru_ej257.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/b6_porsche_996.wav b/sound/acf_extra/vehiclefx/engines/fsp/b6_porsche_996.wav
new file mode 100644
index 000000000..c1c3c5a5c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/b6_porsche_996.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/i4_bmw_s14b23.wav b/sound/acf_extra/vehiclefx/engines/fsp/i4_bmw_s14b23.wav
new file mode 100644
index 000000000..b1b936299
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/i4_bmw_s14b23.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/i4_honda_B18C5.wav b/sound/acf_extra/vehiclefx/engines/fsp/i4_honda_B18C5.wav
new file mode 100644
index 000000000..87a08966f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/i4_honda_B18C5.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/i6_bmw_s54b32.wav b/sound/acf_extra/vehiclefx/engines/fsp/i6_bmw_s54b32.wav
new file mode 100644
index 000000000..b73feacee
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/i6_bmw_s54b32.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/i6_med.wav b/sound/acf_extra/vehiclefx/engines/fsp/i6_med.wav
new file mode 100644
index 000000000..f066361db
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/i6_med.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v10_toyota_1lrgue.wav b/sound/acf_extra/vehiclefx/engines/fsp/v10_toyota_1lrgue.wav
new file mode 100644
index 000000000..592de541d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v10_toyota_1lrgue.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v12_mercedes_m279.wav b/sound/acf_extra/vehiclefx/engines/fsp/v12_mercedes_m279.wav
new file mode 100644
index 000000000..c913aad2c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v12_mercedes_m279.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v6_ferrari_dino.wav b/sound/acf_extra/vehiclefx/engines/fsp/v6_ferrari_dino.wav
new file mode 100644
index 000000000..4a3cffd36
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v6_ferrari_dino.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v6_honda_c32b.wav b/sound/acf_extra/vehiclefx/engines/fsp/v6_honda_c32b.wav
new file mode 100644
index 000000000..9c261b45e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v6_honda_c32b.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v6_nissan_vr38dett.wav b/sound/acf_extra/vehiclefx/engines/fsp/v6_nissan_vr38dett.wav
new file mode 100644
index 000000000..df0db7dd4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v6_nissan_vr38dett.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v8_chrysler_hemi_426_nfs.wav b/sound/acf_extra/vehiclefx/engines/fsp/v8_chrysler_hemi_426_nfs.wav
new file mode 100644
index 000000000..34f862fdb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v8_chrysler_hemi_426_nfs.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v8_gm_duramax_lly.wav b/sound/acf_extra/vehiclefx/engines/fsp/v8_gm_duramax_lly.wav
new file mode 100644
index 000000000..021104b63
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v8_gm_duramax_lly.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/fsp/v8_oldsmobile_455.wav b/sound/acf_extra/vehiclefx/engines/fsp/v8_oldsmobile_455.wav
new file mode 100644
index 000000000..6a32e2503
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/fsp/v8_oldsmobile_455.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gepard.wav b/sound/acf_extra/vehiclefx/engines/gepard.wav
new file mode 100644
index 000000000..57df35cad
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gepard.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/6046.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/6046.wav
new file mode 100644
index 000000000..111bb1eb9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/6046.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/6046down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/6046down.wav
new file mode 100644
index 000000000..17994806d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/6046down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/6046up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/6046up.wav
new file mode 100644
index 000000000..7994b67ad
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/6046up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/av1790.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/av1790.wav
new file mode 100644
index 000000000..cc186eb60
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/av1790.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/av1790off.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/av1790off.wav
new file mode 100644
index 000000000..623ec177f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/av1790off.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/av1790on.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/av1790on.wav
new file mode 100644
index 000000000..aae8e18fe
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/av1790on.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/cunningham.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/cunningham.wav
new file mode 100644
index 000000000..acd27bc18
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/cunningham.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/cunninghamdown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/cunninghamdown.wav
new file mode 100644
index 000000000..bb9dc5382
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/cunninghamdown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/cunninghamup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/cunninghamup.wav
new file mode 100644
index 000000000..472b314ae
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/cunninghamup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/cyclone.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/cyclone.wav
new file mode 100644
index 000000000..13eb7b731
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/cyclone.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/cyclonedown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/cyclonedown.wav
new file mode 100644
index 000000000..5295d79e5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/cyclonedown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/cycloneup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/cycloneup.wav
new file mode 100644
index 000000000..77f1f113d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/cycloneup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/ft.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/ft.wav
new file mode 100644
index 000000000..88824e90f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/ft.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/ftdown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/ftdown.wav
new file mode 100644
index 000000000..97c4188ed
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/ftdown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/ftup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/ftup.wav
new file mode 100644
index 000000000..849d88e27
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/ftup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gaa.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gaa.wav
new file mode 100644
index 000000000..19e296966
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gaa.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gaadown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gaadown.wav
new file mode 100644
index 000000000..9e52f35e8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gaadown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gaaup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gaaup.wav
new file mode 100644
index 000000000..00576c224
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gaaup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gam.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gam.wav
new file mode 100644
index 000000000..67aded790
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gam.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gamdown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gamdown.wav
new file mode 100644
index 000000000..1b543b9fa
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gamdown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gamup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gamup.wav
new file mode 100644
index 000000000..e282d8411
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gamup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gt101.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gt101.wav
new file mode 100644
index 000000000..2dc490bb4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gt101.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gt101down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gt101down.wav
new file mode 100644
index 000000000..bdfa8e238
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gt101down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/gt101up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/gt101up.wav
new file mode 100644
index 000000000..ce2168ba5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/gt101up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/hl42.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/hl42.wav
new file mode 100644
index 000000000..c7e8b4de8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/hl42.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/hl42down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/hl42down.wav
new file mode 100644
index 000000000..5f899df9b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/hl42down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/hl42up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/hl42up.wav
new file mode 100644
index 000000000..c48d5174d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/hl42up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/hl90.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/hl90.wav
new file mode 100644
index 000000000..03b4c3143
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/hl90.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/hl90down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/hl90down.wav
new file mode 100644
index 000000000..42527755a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/hl90down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/hl90up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/hl90up.wav
new file mode 100644
index 000000000..da2066343
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/hl90up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/is7.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/is7.wav
new file mode 100644
index 000000000..a9106d952
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/is7.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/is7down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/is7down.wav
new file mode 100644
index 000000000..f4625105b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/is7down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/is7up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/is7up.wav
new file mode 100644
index 000000000..323dc2fa3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/is7up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2.wav
new file mode 100644
index 000000000..c1e261d12
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2down.wav
new file mode 100644
index 000000000..2bb9e8bc3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2up.wav
new file mode 100644
index 000000000..8ba7ac77d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/l60-2up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/l60.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/l60.wav
new file mode 100644
index 000000000..4dcd57fcb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/l60.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/l60down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/l60down.wav
new file mode 100644
index 000000000..2a1d86b41
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/l60down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/l60up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/l60up.wav
new file mode 100644
index 000000000..2de33f6f3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/l60up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/lafrance.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/lafrance.wav
new file mode 100644
index 000000000..e5a71de9c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/lafrance.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/lafrancedown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/lafrancedown.wav
new file mode 100644
index 000000000..0bb5dd35e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/lafrancedown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/lafranceup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/lafranceup.wav
new file mode 100644
index 000000000..472b314ae
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/lafranceup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/m50.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/m50.wav
new file mode 100644
index 000000000..b28f86970
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/m50.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/m50down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/m50down.wav
new file mode 100644
index 000000000..abf2eb1da
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/m50down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/m50up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/m50up.wav
new file mode 100644
index 000000000..9eba32aa1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/m50up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/m60.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/m60.wav
new file mode 100644
index 000000000..5a55f5995
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/m60.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/m60down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/m60down.wav
new file mode 100644
index 000000000..656b0700b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/m60down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/m60up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/m60up.wav
new file mode 100644
index 000000000..a3b7abb29
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/m60up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/maus.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/maus.wav
new file mode 100644
index 000000000..0e5356a18
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/maus.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/mausdown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/mausdown.wav
new file mode 100644
index 000000000..38d050ea0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/mausdown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/mausup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/mausup.wav
new file mode 100644
index 000000000..72723ae73
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/mausup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/mb605.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/mb605.wav
new file mode 100644
index 000000000..368675ed3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/mb605.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/mb605down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/mb605down.wav
new file mode 100644
index 000000000..bb22c0188
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/mb605down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/mb605up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/mb605up.wav
new file mode 100644
index 000000000..f2e2603a9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/mb605up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/meteor.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/meteor.wav
new file mode 100644
index 000000000..af72e2588
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/meteor.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/meteordown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/meteordown.wav
new file mode 100644
index 000000000..80c893b1c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/meteordown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/meteorup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/meteorup.wav
new file mode 100644
index 000000000..933943347
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/meteorup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/porschediesel.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/porschediesel.wav
new file mode 100644
index 000000000..9e7dc61f3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/porschediesel.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/porschedieseldown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/porschedieseldown.wav
new file mode 100644
index 000000000..da5d38164
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/porschedieseldown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/porschedieselup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/porschedieselup.wav
new file mode 100644
index 000000000..9177e9c24
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/porschedieselup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/praga.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/praga.wav
new file mode 100644
index 000000000..54dd04616
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/praga.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/pragadown.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/pragadown.wav
new file mode 100644
index 000000000..3a0a4cfd6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/pragadown.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/pragaup.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/pragaup.wav
new file mode 100644
index 000000000..8137441f0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/pragaup.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/t64.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/t64.wav
new file mode 100644
index 000000000..3192c6243
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/t64.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/t64down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/t64down.wav
new file mode 100644
index 000000000..d0b5cc699
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/t64down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/t64up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/t64up.wav
new file mode 100644
index 000000000..c70ad8a9f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/t64up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/t71.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/t71.wav
new file mode 100644
index 000000000..3afa9f0d3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/t71.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/t71down.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/t71down.wav
new file mode 100644
index 000000000..0e45a51de
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/t71down.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/t71idle.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/t71idle.wav
new file mode 100644
index 000000000..3e046c8f7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/t71idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gnomefather/t71up.wav b/sound/acf_extra/vehiclefx/engines/gnomefather/t71up.wav
new file mode 100644
index 000000000..170ff4434
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gnomefather/t71up.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/gtk.wav b/sound/acf_extra/vehiclefx/engines/gtk.wav
new file mode 100644
index 000000000..e190819f5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/gtk.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/heavygasengine.wav b/sound/acf_extra/vehiclefx/engines/heavygasengine.wav
new file mode 100644
index 000000000..b5c187f0e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/heavygasengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/hmmwv.wav b/sound/acf_extra/vehiclefx/engines/hmmwv.wav
new file mode 100644
index 000000000..7ecb7fc21
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/hmmwv.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/hmmwv_2.wav b/sound/acf_extra/vehiclefx/engines/hmmwv_2.wav
new file mode 100644
index 000000000..0228d35b5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/hmmwv_2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/hover_loop.wav b/sound/acf_extra/vehiclefx/engines/hover_loop.wav
new file mode 100644
index 000000000..925066788
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/hover_loop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/hover_loop_large.wav b/sound/acf_extra/vehiclefx/engines/hover_loop_large.wav
new file mode 100644
index 000000000..5d6428b2b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/hover_loop_large.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/jagdpanzerkanonenengine.wav b/sound/acf_extra/vehiclefx/engines/jagdpanzerkanonenengine.wav
new file mode 100644
index 000000000..fc30ae74a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/jagdpanzerkanonenengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/jetengine.wav b/sound/acf_extra/vehiclefx/engines/jetengine.wav
new file mode 100644
index 000000000..fa77101cc
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/jetengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/jetstart.wav b/sound/acf_extra/vehiclefx/engines/jetstart.wav
new file mode 100644
index 000000000..cba2fc49c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/jetstart.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/A110I1.WAV b/sound/acf_extra/vehiclefx/engines/l4/A110I1.WAV
new file mode 100644
index 000000000..af9b9040f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/A110I1.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/A110I2.wav b/sound/acf_extra/vehiclefx/engines/l4/A110I2.wav
new file mode 100644
index 000000000..abf647686
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/A110I2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/A110I244.wav b/sound/acf_extra/vehiclefx/engines/l4/A110I244.wav
new file mode 100644
index 000000000..0e608c054
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/A110I244.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/A110I3.wav b/sound/acf_extra/vehiclefx/engines/l4/A110I3.wav
new file mode 100644
index 000000000..59be9e047
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/A110I3.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/Yugo_4_off.wav b/sound/acf_extra/vehiclefx/engines/l4/Yugo_4_off.wav
new file mode 100644
index 000000000..ce112b740
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/Yugo_4_off.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/Yugo_5_on.wav b/sound/acf_extra/vehiclefx/engines/l4/Yugo_5_on.wav
new file mode 100644
index 000000000..4e6668efe
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/Yugo_5_on.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/Yugo_idle.wav b/sound/acf_extra/vehiclefx/engines/l4/Yugo_idle.wav
new file mode 100644
index 000000000..b19d766d1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/Yugo_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/ae86_2000rpm.wav b/sound/acf_extra/vehiclefx/engines/l4/ae86_2000rpm.wav
new file mode 100644
index 000000000..e1bcd842e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/ae86_2000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/ae86_4000rpm.wav b/sound/acf_extra/vehiclefx/engines/l4/ae86_4000rpm.wav
new file mode 100644
index 000000000..9448e3257
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/ae86_4000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/ae86_6000rpm.wav b/sound/acf_extra/vehiclefx/engines/l4/ae86_6000rpm.wav
new file mode 100644
index 000000000..6fb58635b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/ae86_6000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/ae86_8500rpm.wav b/sound/acf_extra/vehiclefx/engines/l4/ae86_8500rpm.wav
new file mode 100644
index 000000000..f999b216b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/ae86_8500rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/ae86_8500rpm2.wav b/sound/acf_extra/vehiclefx/engines/l4/ae86_8500rpm2.wav
new file mode 100644
index 000000000..c875b2cc5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/ae86_8500rpm2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/cortina_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/l4/cortina_onhigh.WAV
new file mode 100644
index 000000000..3463e5d9c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/cortina_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/cortina_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l4/cortina_onlow.WAV
new file mode 100644
index 000000000..1bfa27917
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/cortina_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/cortina_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l4/cortina_onmid.WAV
new file mode 100644
index 000000000..16baba55e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/cortina_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/cortina_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/l4/cortina_onverylow.WAV
new file mode 100644
index 000000000..7a132c5d0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/cortina_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/dp4_idle.wav b/sound/acf_extra/vehiclefx/engines/l4/dp4_idle.wav
new file mode 100644
index 000000000..41fae62d3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/dp4_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/dp4_low.wav b/sound/acf_extra/vehiclefx/engines/l4/dp4_low.wav
new file mode 100644
index 000000000..f57866abe
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/dp4_low.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/dp4_mid.wav b/sound/acf_extra/vehiclefx/engines/l4/dp4_mid.wav
new file mode 100644
index 000000000..0f3c804b2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/dp4_mid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elan_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/l4/elan_onhigh.WAV
new file mode 100644
index 000000000..dcf5ee091
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elan_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elan_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l4/elan_onlow.WAV
new file mode 100644
index 000000000..ecd593df6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elan_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elan_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l4/elan_onmid.WAV
new file mode 100644
index 000000000..1edde2714
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elan_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elan_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/l4/elan_onverylow.WAV
new file mode 100644
index 000000000..29efdacaf
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elan_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elite_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/l4/elite_onhigh.WAV
new file mode 100644
index 000000000..3acc92659
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elite_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elite_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l4/elite_onlow.WAV
new file mode 100644
index 000000000..93e075961
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elite_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elite_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l4/elite_onmid.WAV
new file mode 100644
index 000000000..ceba02419
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elite_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/elite_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/l4/elite_onverylow.WAV
new file mode 100644
index 000000000..46c075a99
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/elite_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/escort_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/l4/escort_onhigh.WAV
new file mode 100644
index 000000000..918d01b5a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/escort_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/escort_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l4/escort_onlow.WAV
new file mode 100644
index 000000000..12df8528e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/escort_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/escort_onlow2.wav b/sound/acf_extra/vehiclefx/engines/l4/escort_onlow2.wav
new file mode 100644
index 000000000..64c02738e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/escort_onlow2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/escort_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l4/escort_onmid.WAV
new file mode 100644
index 000000000..468db3558
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/escort_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/escort_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/l4/escort_onverylow.WAV
new file mode 100644
index 000000000..7505ce487
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/escort_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/mini_onhigh.wav b/sound/acf_extra/vehiclefx/engines/l4/mini_onhigh.wav
new file mode 100644
index 000000000..73c760d00
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/mini_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/mini_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l4/mini_onlow.WAV
new file mode 100644
index 000000000..2e841aed3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/mini_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/mini_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l4/mini_onmid.WAV
new file mode 100644
index 000000000..8a8c312a7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/mini_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/mini_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/l4/mini_onverylow.WAV
new file mode 100644
index 000000000..9844349f7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/mini_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/rc2_onhigh_in.wav b/sound/acf_extra/vehiclefx/engines/l4/rc2_onhigh_in.wav
new file mode 100644
index 000000000..a52e4d1d5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/rc2_onhigh_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/rc2_onlow_in.wav b/sound/acf_extra/vehiclefx/engines/l4/rc2_onlow_in.wav
new file mode 100644
index 000000000..705ad2b63
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/rc2_onlow_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/rc2_onmid_in.wav b/sound/acf_extra/vehiclefx/engines/l4/rc2_onmid_in.wav
new file mode 100644
index 000000000..e32717c28
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/rc2_onmid_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/rc2_onverylow_in.wav b/sound/acf_extra/vehiclefx/engines/l4/rc2_onverylow_in.wav
new file mode 100644
index 000000000..7680401d9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/rc2_onverylow_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/sprint3_onhigh.wav b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onhigh.wav
new file mode 100644
index 000000000..c6e9652b0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/sprint3_onlow.wav b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onlow.wav
new file mode 100644
index 000000000..6496370a5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/sprint3_onmid.wav b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onmid.wav
new file mode 100644
index 000000000..4a8604136
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l4/sprint3_onverylow.wav b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onverylow.wav
new file mode 100644
index 000000000..86ad56c53
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l4/sprint3_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l5/AUDIS1_onmid.wav b/sound/acf_extra/vehiclefx/engines/l5/AUDIS1_onmid.wav
new file mode 100644
index 000000000..289cede5b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l5/AUDIS1_onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONHIGH.WAV b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONHIGH.WAV
new file mode 100644
index 000000000..c9a6c3fc0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONHIGH.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONLOW.WAV b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONLOW.WAV
new file mode 100644
index 000000000..f2bca1332
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONLOW.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONMID.wav b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONMID.wav
new file mode 100644
index 000000000..1a08333ed
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONMID.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONVERYLOW.WAV b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONVERYLOW.WAV
new file mode 100644
index 000000000..e4c285604
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/BMWCSL_ONVERYLOW.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E-type_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/l6/E-type_onhigh.WAV
new file mode 100644
index 000000000..41a54db68
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E-type_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offhigh.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offhigh.wav
new file mode 100644
index 000000000..58e1ffdca
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offlow.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offlow.wav
new file mode 100644
index 000000000..42b4b3798
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offmid.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offmid.wav
new file mode 100644
index 000000000..e87474dbe
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offverylow.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offverylow.wav
new file mode 100644
index 000000000..c46ff85e3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_offverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onhigh.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onhigh.wav
new file mode 100644
index 000000000..0c59bf89d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onlow.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onlow.wav
new file mode 100644
index 000000000..b88a76f21
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onmid.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onmid.wav
new file mode 100644
index 000000000..b20331b1a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onverylow.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onverylow.wav
new file mode 100644
index 000000000..6c34195ce
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_EXT_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_idle.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_idle.wav
new file mode 100644
index 000000000..f455ad98c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/E49_onverylow.wav b/sound/acf_extra/vehiclefx/engines/l6/E49_onverylow.wav
new file mode 100644
index 000000000..5e427ef5c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/E49_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_idle.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_idle.wav
new file mode 100644
index 000000000..4e23e374d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_offhigh.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_offhigh.wav
new file mode 100644
index 000000000..c00295975
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_offhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_offlow.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_offlow.wav
new file mode 100644
index 000000000..e1c8c13ba
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_offlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_offmid.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_offmid.wav
new file mode 100644
index 000000000..cfe6785cc
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_offmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_offverylow.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_offverylow.wav
new file mode 100644
index 000000000..d85fa5eb2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_offverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_onhigh.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_onhigh.wav
new file mode 100644
index 000000000..9e4e1bcae
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_onlow.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_onlow.wav
new file mode 100644
index 000000000..61331d7ba
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_onmid.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_onmid.wav
new file mode 100644
index 000000000..abcb71a0b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/XU1_onverylow.wav b/sound/acf_extra/vehiclefx/engines/l6/XU1_onverylow.wav
new file mode 100644
index 000000000..cf443ecb9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/XU1_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/capri_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/l6/capri_onhigh.WAV
new file mode 100644
index 000000000..dc02e7557
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/capri_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/capri_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l6/capri_onlow.WAV
new file mode 100644
index 000000000..d72a3b64e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/capri_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/capri_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l6/capri_onmid.WAV
new file mode 100644
index 000000000..39c5b06f6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/capri_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/capri_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/l6/capri_onverylow.WAV
new file mode 100644
index 000000000..3aed047f0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/capri_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/e-type_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l6/e-type_onlow.WAV
new file mode 100644
index 000000000..f3de23f12
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/e-type_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/e-type_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l6/e-type_onmid.WAV
new file mode 100644
index 000000000..b2a54dfc3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/e-type_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/e-type_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/l6/e-type_onverylow.WAV
new file mode 100644
index 000000000..c921b5f76
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/e-type_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/gavrilzetamed_acc.wav b/sound/acf_extra/vehiclefx/engines/l6/gavrilzetamed_acc.wav
new file mode 100644
index 000000000..b88a76f21
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/gavrilzetamed_acc.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/mercedes-onhigh.wav b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onhigh.wav
new file mode 100644
index 000000000..bc72c4260
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/mercedes-onlow.wav b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onlow.wav
new file mode 100644
index 000000000..40471aa39
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/mercedes-onmid.wav b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onmid.wav
new file mode 100644
index 000000000..12c25fa82
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/mercedes-onverylow.wav b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onverylow.wav
new file mode 100644
index 000000000..e3a74ffad
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/mercedes-onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/mkII_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/l6/mkII_onhigh.WAV
new file mode 100644
index 000000000..7c350f788
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/mkII_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/mkII_onlow.WAV b/sound/acf_extra/vehiclefx/engines/l6/mkII_onlow.WAV
new file mode 100644
index 000000000..f78905a78
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/mkII_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/mkII_onmid.WAV b/sound/acf_extra/vehiclefx/engines/l6/mkII_onmid.WAV
new file mode 100644
index 000000000..072425ecf
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/mkII_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/r34_10000rpm.wav b/sound/acf_extra/vehiclefx/engines/l6/r34_10000rpm.wav
new file mode 100644
index 000000000..74904c767
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/r34_10000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/r34_2000rpm.wav b/sound/acf_extra/vehiclefx/engines/l6/r34_2000rpm.wav
new file mode 100644
index 000000000..e7b5332da
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/r34_2000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/r34_4000rpm.wav b/sound/acf_extra/vehiclefx/engines/l6/r34_4000rpm.wav
new file mode 100644
index 000000000..e92d0b342
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/r34_4000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/r34_6000rpm.wav b/sound/acf_extra/vehiclefx/engines/l6/r34_6000rpm.wav
new file mode 100644
index 000000000..122acd720
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/r34_6000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/supra_2000rpm.wav b/sound/acf_extra/vehiclefx/engines/l6/supra_2000rpm.wav
new file mode 100644
index 000000000..06e81b586
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/supra_2000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/supra_4000rpm.wav b/sound/acf_extra/vehiclefx/engines/l6/supra_4000rpm.wav
new file mode 100644
index 000000000..1e80e7748
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/supra_4000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/l6/supra_6000rpm.wav b/sound/acf_extra/vehiclefx/engines/l6/supra_6000rpm.wav
new file mode 100644
index 000000000..bda640704
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/l6/supra_6000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/lav.wav b/sound/acf_extra/vehiclefx/engines/lav.wav
new file mode 100644
index 000000000..885542929
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/lav.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/leopard.wav b/sound/acf_extra/vehiclefx/engines/leopard.wav
new file mode 100644
index 000000000..b0f36fc8e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/leopard.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/mammoth_idle.wav b/sound/acf_extra/vehiclefx/engines/mammoth_idle.wav
new file mode 100644
index 000000000..292576096
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/mammoth_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/marder.wav b/sound/acf_extra/vehiclefx/engines/marder.wav
new file mode 100644
index 000000000..c5d98fe19
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/marder.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/maybachhl120.wav b/sound/acf_extra/vehiclefx/engines/maybachhl120.wav
new file mode 100644
index 000000000..0808e492d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/maybachhl120.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/maybachhl120idle.wav b/sound/acf_extra/vehiclefx/engines/maybachhl120idle.wav
new file mode 100644
index 000000000..4db915a5f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/maybachhl120idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/maybachhl230.wav b/sound/acf_extra/vehiclefx/engines/maybachhl230.wav
new file mode 100644
index 000000000..fa2900127
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/maybachhl230.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/maybachhl230idle.wav b/sound/acf_extra/vehiclefx/engines/maybachhl230idle.wav
new file mode 100644
index 000000000..c9b80360a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/maybachhl230idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/nekomanta.wav b/sound/acf_extra/vehiclefx/engines/nekomanta.wav
new file mode 100644
index 000000000..e158c7bf8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/nekomanta.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/nod_apc_idle.wav b/sound/acf_extra/vehiclefx/engines/nod_apc_idle.wav
new file mode 100644
index 000000000..1d58dbc66
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/nod_apc_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/oshkosh.wav b/sound/acf_extra/vehiclefx/engines/oshkosh.wav
new file mode 100644
index 000000000..e802af725
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/oshkosh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/panther.wav b/sound/acf_extra/vehiclefx/engines/panther.wav
new file mode 100644
index 000000000..50960b320
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/panther.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/panzer.wav b/sound/acf_extra/vehiclefx/engines/panzer.wav
new file mode 100644
index 000000000..efef85156
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/panzer.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/ponyengine.wav b/sound/acf_extra/vehiclefx/engines/ponyengine.wav
new file mode 100644
index 000000000..1221cef30
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/ponyengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/pzh2000.wav b/sound/acf_extra/vehiclefx/engines/pzh2000.wav
new file mode 100644
index 000000000..c23eaf1ea
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/pzh2000.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/rover.wav b/sound/acf_extra/vehiclefx/engines/rover.wav
new file mode 100644
index 000000000..519613c75
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/rover.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/rover_2.wav b/sound/acf_extra/vehiclefx/engines/rover_2.wav
new file mode 100644
index 000000000..4db6d953f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/rover_2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/rover_unload.wav b/sound/acf_extra/vehiclefx/engines/rover_unload.wav
new file mode 100644
index 000000000..9aacf7367
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/rover_unload.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/s_heavytankloop.wav b/sound/acf_extra/vehiclefx/engines/s_heavytankloop.wav
new file mode 100644
index 000000000..f832cf9b3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/s_heavytankloop.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/s_mammothtank_loop - Copy.wav b/sound/acf_extra/vehiclefx/engines/s_mammothtank_loop - Copy.wav
new file mode 100644
index 000000000..ec48fb8e6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/s_mammothtank_loop - Copy.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/s_med_tank_idle.wav b/sound/acf_extra/vehiclefx/engines/s_med_tank_idle.wav
new file mode 100644
index 000000000..e7c68c949
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/s_med_tank_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/s_medtank_idle.wav b/sound/acf_extra/vehiclefx/engines/s_medtank_idle.wav
new file mode 100644
index 000000000..6b71ab3cb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/s_medtank_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/scimitar.wav b/sound/acf_extra/vehiclefx/engines/scimitar.wav
new file mode 100644
index 000000000..ef7b1635c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/scimitar.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/sherman.wav b/sound/acf_extra/vehiclefx/engines/sherman.wav
new file mode 100644
index 000000000..c0a5cbf83
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/sherman.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/shermanengine.wav b/sound/acf_extra/vehiclefx/engines/shermanengine.wav
new file mode 100644
index 000000000..dd2b9e685
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/shermanengine.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/shilka.wav b/sound/acf_extra/vehiclefx/engines/shilka.wav
new file mode 100644
index 000000000..84c9fdae1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/shilka.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/starters/gasheavystart.wav b/sound/acf_extra/vehiclefx/engines/starters/gasheavystart.wav
new file mode 100644
index 000000000..832f5d065
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/starters/gasheavystart.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/t55.wav b/sound/acf_extra/vehiclefx/engines/t55.wav
new file mode 100644
index 000000000..a21da8cd3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/t55.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/t62.wav b/sound/acf_extra/vehiclefx/engines/t62.wav
new file mode 100644
index 000000000..d49533137
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/t62.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/t62_2.wav b/sound/acf_extra/vehiclefx/engines/t62_2.wav
new file mode 100644
index 000000000..b916b9afc
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/t62_2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/tank_flame_idle.wav b/sound/acf_extra/vehiclefx/engines/tank_flame_idle.wav
new file mode 100644
index 000000000..f8b8f75d8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/tank_flame_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/tank_light_loop_1.wav b/sound/acf_extra/vehiclefx/engines/tank_light_loop_1.wav
new file mode 100644
index 000000000..c3207c66e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/tank_light_loop_1.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/tank_mammoth_idle.wav b/sound/acf_extra/vehiclefx/engines/tank_mammoth_idle.wav
new file mode 100644
index 000000000..9ad2a64f6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/tank_mammoth_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/tank_medium_idle.wav b/sound/acf_extra/vehiclefx/engines/tank_medium_idle.wav
new file mode 100644
index 000000000..7af0dde7e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/tank_medium_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/tank_stealth_idle.wav b/sound/acf_extra/vehiclefx/engines/tank_stealth_idle.wav
new file mode 100644
index 000000000..4fd6d70ae
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/tank_stealth_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/tiger.wav b/sound/acf_extra/vehiclefx/engines/tiger.wav
new file mode 100644
index 000000000..d0a358fb5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/tiger.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/titan.wav b/sound/acf_extra/vehiclefx/engines/titan.wav
new file mode 100644
index 000000000..220bfe6cb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/titan.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/trojan.wav b/sound/acf_extra/vehiclefx/engines/trojan.wav
new file mode 100644
index 000000000..d1c8e6973
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/trojan.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v10/Viper_On.wav b/sound/acf_extra/vehiclefx/engines/v10/Viper_On.wav
new file mode 100644
index 000000000..ca67abbb0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v10/Viper_On.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBR9_onhigh.wav b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onhigh.wav
new file mode 100644
index 000000000..d671a0f86
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBR9_onlow.wav b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onlow.wav
new file mode 100644
index 000000000..bfc986fb0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBR9_onmid.wav b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onmid.wav
new file mode 100644
index 000000000..1e79b936d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBR9_onverylow.wav b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onverylow.wav
new file mode 100644
index 000000000..cfe9807f5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBR9_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onhigh_ex.wav b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onhigh_ex.wav
new file mode 100644
index 000000000..913e8a247
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onhigh_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onlow_ex.wav b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onlow_ex.wav
new file mode 100644
index 000000000..505294292
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onlow_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onmid_ex.wav b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onmid_ex.wav
new file mode 100644
index 000000000..6ed553ec1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onmid_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onverylow_ex.wav b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onverylow_ex.wav
new file mode 100644
index 000000000..2e81e7459
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/DBRS9_onverylow_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_high.wav b/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_high.wav
new file mode 100644
index 000000000..12a3a7127
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_high.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_low.wav b/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_low.wav
new file mode 100644
index 000000000..4e6eccad7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_low.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_mid.wav b/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_mid.wav
new file mode 100644
index 000000000..4aa893d24
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/Zonda_on_mid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/gtb4_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onhigh.WAV
new file mode 100644
index 000000000..78d5117b4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/gtb4_onlow.WAV b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onlow.WAV
new file mode 100644
index 000000000..52d8dde90
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/gtb4_onmid.WAV b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onmid.WAV
new file mode 100644
index 000000000..c684d6ee5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/gtb4_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onverylow.WAV
new file mode 100644
index 000000000..75655225a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/gtb4_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12.wav b/sound/acf_extra/vehiclefx/engines/v12/v12.wav
new file mode 100644
index 000000000..9cf6f42a0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d1.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d1.wav
new file mode 100644
index 000000000..265a3c11f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d1.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d1high.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d1high.wav
new file mode 100644
index 000000000..d6df733a7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d1high.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d2.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d2.wav
new file mode 100644
index 000000000..d9e2fe1d5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d2high.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d2high.wav
new file mode 100644
index 000000000..5c19057d3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d2high.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d3.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d3.wav
new file mode 100644
index 000000000..87e9b30f0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d3.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d3high.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d3high.wav
new file mode 100644
index 000000000..809f178a9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d3high.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d4.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d4.wav
new file mode 100644
index 000000000..056ad7e26
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d4.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v12/v12d4high.wav b/sound/acf_extra/vehiclefx/engines/v12/v12d4high.wav
new file mode 100644
index 000000000..cedb8fa98
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v12/v12d4high.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v6/350z_2000rpm.wav b/sound/acf_extra/vehiclefx/engines/v6/350z_2000rpm.wav
new file mode 100644
index 000000000..50ae1c01d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v6/350z_2000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v6/350z_4000rpm.wav b/sound/acf_extra/vehiclefx/engines/v6/350z_4000rpm.wav
new file mode 100644
index 000000000..8eb5c613b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v6/350z_4000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v6/350z_6000rpm.wav b/sound/acf_extra/vehiclefx/engines/v6/350z_6000rpm.wav
new file mode 100644
index 000000000..9d5451141
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v6/350z_6000rpm.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v6/gavrilzetamed_acc.wav b/sound/acf_extra/vehiclefx/engines/v6/gavrilzetamed_acc.wav
new file mode 100644
index 000000000..915dacb82
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v6/gavrilzetamed_acc.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v6/metro_onhigh.wav b/sound/acf_extra/vehiclefx/engines/v6/metro_onhigh.wav
new file mode 100644
index 000000000..cb0c370ea
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v6/metro_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v6/newv6.wav b/sound/acf_extra/vehiclefx/engines/v6/newv6.wav
new file mode 100644
index 000000000..855a36368
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v6/newv6.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v6/test.wav b/sound/acf_extra/vehiclefx/engines/v6/test.wav
new file mode 100644
index 000000000..32963484f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v6/test.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8.wav b/sound/acf_extra/vehiclefx/engines/v8.wav
new file mode 100644
index 000000000..c1f85f204
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onhigh_in.wav b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onhigh_in.wav
new file mode 100644
index 000000000..6f713296f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onhigh_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onlow_in.wav b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onlow_in.wav
new file mode 100644
index 000000000..0e89d3191
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onlow_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onmid_in.wav b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onmid_in.wav
new file mode 100644
index 000000000..ce05c1641
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp1_onmid_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp3_onhigh_in.wav b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp3_onhigh_in.wav
new file mode 100644
index 000000000..b754e964b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp3_onhigh_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp3_onlow_in.wav b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp3_onlow_in.wav
new file mode 100644
index 000000000..c7061ca1b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/38LV8_gp3_onlow_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/BAR_onverylow.wav b/sound/acf_extra/vehiclefx/engines/v8/BAR_onverylow.wav
new file mode 100644
index 000000000..2304457b1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/BAR_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/CU2_idle_ex.wav b/sound/acf_extra/vehiclefx/engines/v8/CU2_idle_ex.wav
new file mode 100644
index 000000000..42902464e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/CU2_idle_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/CU2_offlow_ex.wav b/sound/acf_extra/vehiclefx/engines/v8/CU2_offlow_ex.wav
new file mode 100644
index 000000000..f982c7dff
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/CU2_offlow_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/CU2_onhigh_ex.wav b/sound/acf_extra/vehiclefx/engines/v8/CU2_onhigh_ex.wav
new file mode 100644
index 000000000..37a1239bd
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/CU2_onhigh_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/CU2_startup_ex.wav b/sound/acf_extra/vehiclefx/engines/v8/CU2_startup_ex.wav
new file mode 100644
index 000000000..2e9484a68
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/CU2_startup_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offhighEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offhighEX.wav
new file mode 100644
index 000000000..c7d082ff4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offhighEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offlowEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offlowEX.wav
new file mode 100644
index 000000000..003dfa7c4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offlowEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offmidEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offmidEX.wav
new file mode 100644
index 000000000..ecacd2bdc
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offmidEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offverylowEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offverylowEX.wav
new file mode 100644
index 000000000..e86bec2d6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_offverylowEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onhighEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onhighEX.wav
new file mode 100644
index 000000000..fb17a9e38
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onhighEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onlowEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onlowEX.wav
new file mode 100644
index 000000000..556316a8a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onlowEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onmidEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onmidEX.wav
new file mode 100644
index 000000000..92206e69e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onmidEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onverylowEX.wav b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onverylowEX.wav
new file mode 100644
index 000000000..aa791b625
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/ClevV8_onverylowEX.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/GTO_onhigh.wav b/sound/acf_extra/vehiclefx/engines/v8/GTO_onhigh.wav
new file mode 100644
index 000000000..65b901d3e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/GTO_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/GTO_onlow.wav b/sound/acf_extra/vehiclefx/engines/v8/GTO_onlow.wav
new file mode 100644
index 000000000..fbefa81ef
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/GTO_onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/GTO_onmid.wav b/sound/acf_extra/vehiclefx/engines/v8/GTO_onmid.wav
new file mode 100644
index 000000000..066f8aa34
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/GTO_onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onhigh.wav b/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onhigh.wav
new file mode 100644
index 000000000..2b463184d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onlow.wav b/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onlow.wav
new file mode 100644
index 000000000..93e5d612d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onverylow.wav b/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onverylow.wav
new file mode 100644
index 000000000..96caba9b6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/HTGTS_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/MU2_idle_ex.wav b/sound/acf_extra/vehiclefx/engines/v8/MU2_idle_ex.wav
new file mode 100644
index 000000000..96383a6a6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/MU2_idle_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/NV2_onlow_ex.wav b/sound/acf_extra/vehiclefx/engines/v8/NV2_onlow_ex.wav
new file mode 100644
index 000000000..797e0f136
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/NV2_onlow_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/cobra_onhigh.WAV b/sound/acf_extra/vehiclefx/engines/v8/cobra_onhigh.WAV
new file mode 100644
index 000000000..db32354cf
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/cobra_onhigh.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/cobra_onlow.WAV b/sound/acf_extra/vehiclefx/engines/v8/cobra_onlow.WAV
new file mode 100644
index 000000000..a4d487338
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/cobra_onlow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/cobra_onmid.WAV b/sound/acf_extra/vehiclefx/engines/v8/cobra_onmid.WAV
new file mode 100644
index 000000000..e80aa6f89
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/cobra_onmid.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/cobra_onverylow.WAV b/sound/acf_extra/vehiclefx/engines/v8/cobra_onverylow.WAV
new file mode 100644
index 000000000..43954a682
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/cobra_onverylow.WAV differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/cobra_onverylow2.wav b/sound/acf_extra/vehiclefx/engines/v8/cobra_onverylow2.wav
new file mode 100644
index 000000000..cefdbb35b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/cobra_onverylow2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/corvette69-onhigh.wav b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onhigh.wav
new file mode 100644
index 000000000..81a9b0f36
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/corvette69-onlow.wav b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onlow.wav
new file mode 100644
index 000000000..acd399808
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onlow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/corvette69-onmid.wav b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onmid.wav
new file mode 100644
index 000000000..fa5c6bcd5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/corvette69-onverylow.wav b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onverylow.wav
new file mode 100644
index 000000000..600b14567
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/corvette69-onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/driver1.wav b/sound/acf_extra/vehiclefx/engines/v8/driver1.wav
new file mode 100644
index 000000000..ed6917a6a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/driver1.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/v8high.wav b/sound/acf_extra/vehiclefx/engines/v8/v8high.wav
new file mode 100644
index 000000000..556a79850
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/v8high.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/v8/v8high2.wav b/sound/acf_extra/vehiclefx/engines/v8/v8high2.wav
new file mode 100644
index 000000000..60dce2d67
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/v8/v8high2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_4000.wav b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_4000.wav
new file mode 100644
index 000000000..584d316bb
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_4000.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_7000.wav b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_7000.wav
new file mode 100644
index 000000000..671ae5ea5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_7000.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_offhigh.wav b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_offhigh.wav
new file mode 100644
index 000000000..fef93ce42
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_offhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_offmid.wav b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_offmid.wav
new file mode 100644
index 000000000..225646b32
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/wankel/Ex_rx8_offmid.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/wankel/rx7.wav b/sound/acf_extra/vehiclefx/engines/wankel/rx7.wav
new file mode 100644
index 000000000..2e04981f5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/wankel/rx7.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/warrior.wav b/sound/acf_extra/vehiclefx/engines/warrior.wav
new file mode 100644
index 000000000..e0ea48662
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/warrior.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/warrior_2.wav b/sound/acf_extra/vehiclefx/engines/warrior_2.wav
new file mode 100644
index 000000000..541b8da40
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/warrior_2.wav differ
diff --git a/sound/acf_extra/vehiclefx/engines/warthog.wav b/sound/acf_extra/vehiclefx/engines/warthog.wav
new file mode 100644
index 000000000..431b4c482
Binary files /dev/null and b/sound/acf_extra/vehiclefx/engines/warthog.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/backupbeep.wav b/sound/acf_extra/vehiclefx/horn/backupbeep.wav
new file mode 100644
index 000000000..1cd8e6ab7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/backupbeep.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/epichorn.wav b/sound/acf_extra/vehiclefx/horn/epichorn.wav
new file mode 100644
index 000000000..94b15fe60
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/epichorn.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn0.wav b/sound/acf_extra/vehiclefx/horn/horn0.wav
new file mode 100644
index 000000000..0d0371251
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn0.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn1.wav b/sound/acf_extra/vehiclefx/horn/horn1.wav
new file mode 100644
index 000000000..043c4a5e8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn1.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn10.wav b/sound/acf_extra/vehiclefx/horn/horn10.wav
new file mode 100644
index 000000000..7b3241687
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn10.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn11.wav b/sound/acf_extra/vehiclefx/horn/horn11.wav
new file mode 100644
index 000000000..5370089b8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn11.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn12.wav b/sound/acf_extra/vehiclefx/horn/horn12.wav
new file mode 100644
index 000000000..f7e191ed8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn12.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn13.wav b/sound/acf_extra/vehiclefx/horn/horn13.wav
new file mode 100644
index 000000000..148a91dda
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn13.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn14.wav b/sound/acf_extra/vehiclefx/horn/horn14.wav
new file mode 100644
index 000000000..00674b17f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn14.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn15.wav b/sound/acf_extra/vehiclefx/horn/horn15.wav
new file mode 100644
index 000000000..ed72af230
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn15.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn16.wav b/sound/acf_extra/vehiclefx/horn/horn16.wav
new file mode 100644
index 000000000..be72734a7
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn16.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn17.wav b/sound/acf_extra/vehiclefx/horn/horn17.wav
new file mode 100644
index 000000000..1fbd891ed
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn17.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn18.wav b/sound/acf_extra/vehiclefx/horn/horn18.wav
new file mode 100644
index 000000000..9ff2d5897
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn18.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn19.wav b/sound/acf_extra/vehiclefx/horn/horn19.wav
new file mode 100644
index 000000000..fe65d2790
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn19.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn2.wav b/sound/acf_extra/vehiclefx/horn/horn2.wav
new file mode 100644
index 000000000..0d1a6ea97
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn2.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn3.wav b/sound/acf_extra/vehiclefx/horn/horn3.wav
new file mode 100644
index 000000000..7012d25ff
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn3.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn4.wav b/sound/acf_extra/vehiclefx/horn/horn4.wav
new file mode 100644
index 000000000..d076d84a6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn4.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn5.wav b/sound/acf_extra/vehiclefx/horn/horn5.wav
new file mode 100644
index 000000000..0d9149c48
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn5.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn6.wav b/sound/acf_extra/vehiclefx/horn/horn6.wav
new file mode 100644
index 000000000..535c8060d
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn6.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn7.wav b/sound/acf_extra/vehiclefx/horn/horn7.wav
new file mode 100644
index 000000000..e16395066
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn7.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn8.wav b/sound/acf_extra/vehiclefx/horn/horn8.wav
new file mode 100644
index 000000000..88cc66632
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn8.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/horn9.wav b/sound/acf_extra/vehiclefx/horn/horn9.wav
new file mode 100644
index 000000000..d7e13f785
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/horn9.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/hornb1_int.wav b/sound/acf_extra/vehiclefx/horn/hornb1_int.wav
new file mode 100644
index 000000000..d334ccad3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/hornb1_int.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/hornb2_int.wav b/sound/acf_extra/vehiclefx/horn/hornb2_int.wav
new file mode 100644
index 000000000..8ef1c1d76
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/hornb2_int.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/hornb3_int.wav b/sound/acf_extra/vehiclefx/horn/hornb3_int.wav
new file mode 100644
index 000000000..f6d3100a3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/hornb3_int.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/hornupgrade_in.wav b/sound/acf_extra/vehiclefx/horn/hornupgrade_in.wav
new file mode 100644
index 000000000..d8a72fca8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/hornupgrade_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/hupe.wav b/sound/acf_extra/vehiclefx/horn/hupe.wav
new file mode 100644
index 000000000..d57b95345
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/hupe.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/old_horn.wav b/sound/acf_extra/vehiclefx/horn/old_horn.wav
new file mode 100644
index 000000000..01cc98d71
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/old_horn.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/s_sov_demohorn2.wav b/sound/acf_extra/vehiclefx/horn/s_sov_demohorn2.wav
new file mode 100644
index 000000000..3627c1d93
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/s_sov_demohorn2.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/s_sov_demohorn3.wav b/sound/acf_extra/vehiclefx/horn/s_sov_demohorn3.wav
new file mode 100644
index 000000000..507716052
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/s_sov_demohorn3.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/train horn.wav b/sound/acf_extra/vehiclefx/horn/train horn.wav
new file mode 100644
index 000000000..d56614ef1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/train horn.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/truck_horn.wav b/sound/acf_extra/vehiclefx/horn/truck_horn.wav
new file mode 100644
index 000000000..5dce30f13
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/truck_horn.wav differ
diff --git a/sound/acf_extra/vehiclefx/horn/truckhorn.wav b/sound/acf_extra/vehiclefx/horn/truckhorn.wav
new file mode 100644
index 000000000..b33894084
Binary files /dev/null and b/sound/acf_extra/vehiclefx/horn/truckhorn.wav differ
diff --git a/sound/acf_extra/vehiclefx/idle/diesel1.wav b/sound/acf_extra/vehiclefx/idle/diesel1.wav
new file mode 100644
index 000000000..fbac7e5aa
Binary files /dev/null and b/sound/acf_extra/vehiclefx/idle/diesel1.wav differ
diff --git a/sound/acf_extra/vehiclefx/idle/diesel2.wav b/sound/acf_extra/vehiclefx/idle/diesel2.wav
new file mode 100644
index 000000000..acb9751ad
Binary files /dev/null and b/sound/acf_extra/vehiclefx/idle/diesel2.wav differ
diff --git a/sound/acf_extra/vehiclefx/idle/diesel3.wav b/sound/acf_extra/vehiclefx/idle/diesel3.wav
new file mode 100644
index 000000000..162118954
Binary files /dev/null and b/sound/acf_extra/vehiclefx/idle/diesel3.wav differ
diff --git a/sound/acf_extra/vehiclefx/idle/diesel4.wav b/sound/acf_extra/vehiclefx/idle/diesel4.wav
new file mode 100644
index 000000000..0d6174f7b
Binary files /dev/null and b/sound/acf_extra/vehiclefx/idle/diesel4.wav differ
diff --git a/sound/acf_extra/vehiclefx/idle/diesel5.wav b/sound/acf_extra/vehiclefx/idle/diesel5.wav
new file mode 100644
index 000000000..0f4e8b9d4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/idle/diesel5.wav differ
diff --git a/sound/acf_extra/vehiclefx/idle/diesel7.wav b/sound/acf_extra/vehiclefx/idle/diesel7.wav
new file mode 100644
index 000000000..b9237e3e3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/idle/diesel7.wav differ
diff --git a/sound/acf_extra/vehiclefx/idle/s_supply_truck_idle.wav b/sound/acf_extra/vehiclefx/idle/s_supply_truck_idle.wav
new file mode 100644
index 000000000..bc04a2d8f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/idle/s_supply_truck_idle.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/air_01.wav b/sound/acf_extra/vehiclefx/misc/air_01.wav
new file mode 100644
index 000000000..555648ed9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/air_01.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/air_04.wav b/sound/acf_extra/vehiclefx/misc/air_04.wav
new file mode 100644
index 000000000..74a127fc1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/air_04.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/air_07.wav b/sound/acf_extra/vehiclefx/misc/air_07.wav
new file mode 100644
index 000000000..14ae04358
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/air_07.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/air_brake1.wav b/sound/acf_extra/vehiclefx/misc/air_brake1.wav
new file mode 100644
index 000000000..78ca827e1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/air_brake1.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/air_brake2.wav b/sound/acf_extra/vehiclefx/misc/air_brake2.wav
new file mode 100644
index 000000000..b15ad8fcc
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/air_brake2.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/keys.wav b/sound/acf_extra/vehiclefx/misc/keys.wav
new file mode 100644
index 000000000..c39a37ae6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/keys.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/reverse.wav b/sound/acf_extra/vehiclefx/misc/reverse.wav
new file mode 100644
index 000000000..651d5f26e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/reverse.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/siren.WAV b/sound/acf_extra/vehiclefx/misc/siren.WAV
new file mode 100644
index 000000000..739e418c3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/siren.WAV differ
diff --git a/sound/acf_extra/vehiclefx/misc/windexternal.wav b/sound/acf_extra/vehiclefx/misc/windexternal.wav
new file mode 100644
index 000000000..0284cf0e9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/windexternal.wav differ
diff --git a/sound/acf_extra/vehiclefx/misc/windrush_in.wav b/sound/acf_extra/vehiclefx/misc/windrush_in.wav
new file mode 100644
index 000000000..583cb28f1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/misc/windrush_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/apcstart1.wav b/sound/acf_extra/vehiclefx/starters/apcstart1.wav
new file mode 100644
index 000000000..70ddca000
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/apcstart1.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/gdi_apc_start.wav b/sound/acf_extra/vehiclefx/starters/gdi_apc_start.wav
new file mode 100644
index 000000000..7e825b90c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/gdi_apc_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/hmmwv_start.wav b/sound/acf_extra/vehiclefx/starters/hmmwv_start.wav
new file mode 100644
index 000000000..6c05a3f12
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/hmmwv_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/hover_start.wav b/sound/acf_extra/vehiclefx/starters/hover_start.wav
new file mode 100644
index 000000000..073deb186
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/hover_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/mammutstart.wav b/sound/acf_extra/vehiclefx/starters/mammutstart.wav
new file mode 100644
index 000000000..2c864d8c6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/mammutstart.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/recon_bike_start.wav b/sound/acf_extra/vehiclefx/starters/recon_bike_start.wav
new file mode 100644
index 000000000..bee9128a9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/recon_bike_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/s_heavytankstart.wav b/sound/acf_extra/vehiclefx/starters/s_heavytankstart.wav
new file mode 100644
index 000000000..b87641e04
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/s_heavytankstart.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/s_mammothtank_start.wav b/sound/acf_extra/vehiclefx/starters/s_mammothtank_start.wav
new file mode 100644
index 000000000..721a544f5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/s_mammothtank_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/s_med_tank_start.wav b/sound/acf_extra/vehiclefx/starters/s_med_tank_start.wav
new file mode 100644
index 000000000..61d5fcae1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/s_med_tank_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/s_rangerstart.wav b/sound/acf_extra/vehiclefx/starters/s_rangerstart.wav
new file mode 100644
index 000000000..1492afe18
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/s_rangerstart.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/starter1.wav b/sound/acf_extra/vehiclefx/starters/starter1.wav
new file mode 100644
index 000000000..c9e74d7d3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/starter1.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/starter2.wav b/sound/acf_extra/vehiclefx/starters/starter2.wav
new file mode 100644
index 000000000..38e5b4402
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/starter2.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/starter3.wav b/sound/acf_extra/vehiclefx/starters/starter3.wav
new file mode 100644
index 000000000..ca45e6a08
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/starter3.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/starter4.wav b/sound/acf_extra/vehiclefx/starters/starter4.wav
new file mode 100644
index 000000000..fb976fe15
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/starter4.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/starter5.wav b/sound/acf_extra/vehiclefx/starters/starter5.wav
new file mode 100644
index 000000000..e350005a5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/starter5.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/starter6.wav b/sound/acf_extra/vehiclefx/starters/starter6.wav
new file mode 100644
index 000000000..97d162f3c
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/starter6.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/starter7.wav b/sound/acf_extra/vehiclefx/starters/starter7.wav
new file mode 100644
index 000000000..67ebfdf2f
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/starter7.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/tank_light_start.wav b/sound/acf_extra/vehiclefx/starters/tank_light_start.wav
new file mode 100644
index 000000000..7184c493a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/tank_light_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/tank_mammoth_start.wav b/sound/acf_extra/vehiclefx/starters/tank_mammoth_start.wav
new file mode 100644
index 000000000..623af91ad
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/tank_mammoth_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/tank_medium_start.wav b/sound/acf_extra/vehiclefx/starters/tank_medium_start.wav
new file mode 100644
index 000000000..9957565b0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/tank_medium_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/starters/tank_stealth_start.wav b/sound/acf_extra/vehiclefx/starters/tank_stealth_start.wav
new file mode 100644
index 000000000..7d819e073
Binary files /dev/null and b/sound/acf_extra/vehiclefx/starters/tank_stealth_start.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/concretetireskid.wav b/sound/acf_extra/vehiclefx/tires/concretetireskid.wav
new file mode 100644
index 000000000..ae914efd1
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/concretetireskid.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/dirtroll.wav b/sound/acf_extra/vehiclefx/tires/dirtroll.wav
new file mode 100644
index 000000000..ebd2917c5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/dirtroll.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/dirtskid.wav b/sound/acf_extra/vehiclefx/tires/dirtskid.wav
new file mode 100644
index 000000000..cfe1a4eee
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/dirtskid.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/grassroll.wav b/sound/acf_extra/vehiclefx/tires/grassroll.wav
new file mode 100644
index 000000000..f5ea2c3a3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/grassroll.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/grassskid.wav b/sound/acf_extra/vehiclefx/tires/grassskid.wav
new file mode 100644
index 000000000..caa8bba86
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/grassskid.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/gwv1EB2.tmp b/sound/acf_extra/vehiclefx/tires/gwv1EB2.tmp
new file mode 100644
index 000000000..33e966454
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/gwv1EB2.tmp differ
diff --git a/sound/acf_extra/vehiclefx/tires/road.wav b/sound/acf_extra/vehiclefx/tires/road.wav
new file mode 100644
index 000000000..c9ceee5e0
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/road.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/scrub1_dry_in.wav b/sound/acf_extra/vehiclefx/tires/scrub1_dry_in.wav
new file mode 100644
index 000000000..01edcf2e9
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/scrub1_dry_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/scrub3_dry_in.wav b/sound/acf_extra/vehiclefx/tires/scrub3_dry_in.wav
new file mode 100644
index 000000000..24f01c7af
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/scrub3_dry_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/scrub5_dry_in.wav b/sound/acf_extra/vehiclefx/tires/scrub5_dry_in.wav
new file mode 100644
index 000000000..94671bdea
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/scrub5_dry_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/scrub6_dry_in.wav b/sound/acf_extra/vehiclefx/tires/scrub6_dry_in.wav
new file mode 100644
index 000000000..3bd0a9198
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/scrub6_dry_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/scrub9_dry_in.wav b/sound/acf_extra/vehiclefx/tires/scrub9_dry_in.wav
new file mode 100644
index 000000000..d5226cea6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/scrub9_dry_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/skid2_dry_ex.wav b/sound/acf_extra/vehiclefx/tires/skid2_dry_ex.wav
new file mode 100644
index 000000000..3828d4a82
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/skid2_dry_ex.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/skid3_dry_in.wav b/sound/acf_extra/vehiclefx/tires/skid3_dry_in.wav
new file mode 100644
index 000000000..76dda1fd4
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/skid3_dry_in.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/skidgrass.wav b/sound/acf_extra/vehiclefx/tires/skidgrass.wav
new file mode 100644
index 000000000..3a0bf0151
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/skidgrass.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/skidroadheavymajor.wav b/sound/acf_extra/vehiclefx/tires/skidroadheavymajor.wav
new file mode 100644
index 000000000..5220d3ed6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/skidroadheavymajor.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/skidroadheavyminor.wav b/sound/acf_extra/vehiclefx/tires/skidroadheavyminor.wav
new file mode 100644
index 000000000..98687b8f2
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/skidroadheavyminor.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/skidroadheavypre.wav b/sound/acf_extra/vehiclefx/tires/skidroadheavypre.wav
new file mode 100644
index 000000000..7343cfe0a
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/skidroadheavypre.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/skidroadlight.wav b/sound/acf_extra/vehiclefx/tires/skidroadlight.wav
new file mode 100644
index 000000000..13629383e
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/skidroadlight.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/snowroll.wav b/sound/acf_extra/vehiclefx/tires/snowroll.wav
new file mode 100644
index 000000000..a43e9dfd3
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/snowroll.wav differ
diff --git a/sound/acf_extra/vehiclefx/tires/woodroll.wav b/sound/acf_extra/vehiclefx/tires/woodroll.wav
new file mode 100644
index 000000000..b1bc56a14
Binary files /dev/null and b/sound/acf_extra/vehiclefx/tires/woodroll.wav differ
diff --git a/sound/acf_extra/vehiclefx/trans/default_shift.wav b/sound/acf_extra/vehiclefx/trans/default_shift.wav
new file mode 100644
index 000000000..1034fa1a6
Binary files /dev/null and b/sound/acf_extra/vehiclefx/trans/default_shift.wav differ
diff --git a/sound/acf_extra/vehiclefx/trans/gearwhine.wav b/sound/acf_extra/vehiclefx/trans/gearwhine.wav
new file mode 100644
index 000000000..01031d347
Binary files /dev/null and b/sound/acf_extra/vehiclefx/trans/gearwhine.wav differ
diff --git a/sound/acf_extra/vehiclefx/trans/gearwhine2.wav b/sound/acf_extra/vehiclefx/trans/gearwhine2.wav
new file mode 100644
index 000000000..eaf4b7058
Binary files /dev/null and b/sound/acf_extra/vehiclefx/trans/gearwhine2.wav differ
diff --git a/sound/acf_extra/vehiclefx/trans/trans.wav b/sound/acf_extra/vehiclefx/trans/trans.wav
new file mode 100644
index 000000000..13c57e7a8
Binary files /dev/null and b/sound/acf_extra/vehiclefx/trans/trans.wav differ
diff --git a/sound/acf_extra/vehiclefx/trans/tw_onhigh.wav b/sound/acf_extra/vehiclefx/trans/tw_onhigh.wav
new file mode 100644
index 000000000..25ed34ac5
Binary files /dev/null and b/sound/acf_extra/vehiclefx/trans/tw_onhigh.wav differ
diff --git a/sound/acf_extra/vehiclefx/trans/tw_onverylow.wav b/sound/acf_extra/vehiclefx/trans/tw_onverylow.wav
new file mode 100644
index 000000000..9ee657c44
Binary files /dev/null and b/sound/acf_extra/vehiclefx/trans/tw_onverylow.wav differ
diff --git a/sound/acf_extra/vehiclefx/trans/yest.wav b/sound/acf_extra/vehiclefx/trans/yest.wav
new file mode 100644
index 000000000..bd50bee15
Binary files /dev/null and b/sound/acf_extra/vehiclefx/trans/yest.wav differ
diff --git a/sound/acf_other/penetratingshots/00000292.wav b/sound/acf_other/penetratingshots/00000292.wav
new file mode 100644
index 000000000..c3f1ac985
Binary files /dev/null and b/sound/acf_other/penetratingshots/00000292.wav differ
diff --git a/sound/acf_other/penetratingshots/00000293.wav b/sound/acf_other/penetratingshots/00000293.wav
new file mode 100644
index 000000000..8a9f9465e
Binary files /dev/null and b/sound/acf_other/penetratingshots/00000293.wav differ
diff --git a/sound/acf_other/penetratingshots/00000294.wav b/sound/acf_other/penetratingshots/00000294.wav
new file mode 100644
index 000000000..cdf491aa6
Binary files /dev/null and b/sound/acf_other/penetratingshots/00000294.wav differ
diff --git a/sound/acf_other/penetratingshots/00000295.wav b/sound/acf_other/penetratingshots/00000295.wav
new file mode 100644
index 000000000..16d3ec504
Binary files /dev/null and b/sound/acf_other/penetratingshots/00000295.wav differ
diff --git a/sound/acf_other/penetratingshots/00000296.wav b/sound/acf_other/penetratingshots/00000296.wav
new file mode 100644
index 000000000..fbd62226a
Binary files /dev/null and b/sound/acf_other/penetratingshots/00000296.wav differ
diff --git a/sound/acf_other/penetratingshots/00000297.wav b/sound/acf_other/penetratingshots/00000297.wav
new file mode 100644
index 000000000..886086c40
Binary files /dev/null and b/sound/acf_other/penetratingshots/00000297.wav differ
diff --git a/sound/acf_other/ricochets/00000320.wav b/sound/acf_other/ricochets/00000320.wav
new file mode 100644
index 000000000..e540b3757
Binary files /dev/null and b/sound/acf_other/ricochets/00000320.wav differ
diff --git a/sound/acf_other/ricochets/00000321.wav b/sound/acf_other/ricochets/00000321.wav
new file mode 100644
index 000000000..97c3da765
Binary files /dev/null and b/sound/acf_other/ricochets/00000321.wav differ
diff --git a/sound/acf_other/ricochets/00000322.wav b/sound/acf_other/ricochets/00000322.wav
new file mode 100644
index 000000000..7babe4eb4
Binary files /dev/null and b/sound/acf_other/ricochets/00000322.wav differ
diff --git a/sound/acf_other/ricochets/00000323.wav b/sound/acf_other/ricochets/00000323.wav
new file mode 100644
index 000000000..8e5ca9833
Binary files /dev/null and b/sound/acf_other/ricochets/00000323.wav differ
diff --git a/sound/weapons/ACF_Gun/ac_fire.wav b/sound/weapons/acf_gun/ac_fire.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/ac_fire.wav
rename to sound/weapons/acf_gun/ac_fire.wav
diff --git a/sound/weapons/ACF_Gun/AC_Fire1.wav b/sound/weapons/acf_gun/ac_fire1.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/AC_Fire1.wav
rename to sound/weapons/acf_gun/ac_fire1.wav
diff --git a/sound/weapons/ACF_Gun/AC_Fire3.wav b/sound/weapons/acf_gun/ac_fire3.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/AC_Fire3.wav
rename to sound/weapons/acf_gun/ac_fire3.wav
diff --git a/sound/weapons/acf_gun/ac_fire4.wav b/sound/weapons/acf_gun/ac_fire4.wav
new file mode 100644
index 000000000..a7a8cb8a2
Binary files /dev/null and b/sound/weapons/acf_gun/ac_fire4.wav differ
diff --git a/sound/weapons/ACF_Gun/ac_fire4.wav b/sound/weapons/acf_gun/ac_fire4_old.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/ac_fire4.wav
rename to sound/weapons/acf_gun/ac_fire4_old.wav
diff --git a/sound/weapons/ACF_Gun/autoloader.wav b/sound/weapons/acf_gun/autoloader.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/autoloader.wav
rename to sound/weapons/acf_gun/autoloader.wav
diff --git a/sound/weapons/ACF_Gun/cannon_fire3.wav b/sound/weapons/acf_gun/cannon_fire3.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/cannon_fire3.wav
rename to sound/weapons/acf_gun/cannon_fire3.wav
diff --git a/sound/weapons/ACF_Gun/cannon_new.wav b/sound/weapons/acf_gun/cannon_new.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/cannon_new.wav
rename to sound/weapons/acf_gun/cannon_new.wav
diff --git a/sound/weapons/ACF_Gun/distancecannon.wav b/sound/weapons/acf_gun/distancecannon.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/distancecannon.wav
rename to sound/weapons/acf_gun/distancecannon.wav
diff --git a/sound/weapons/ACF_Gun/distancehowitzer.wav b/sound/weapons/acf_gun/distancehowitzer.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/distancehowitzer.wav
rename to sound/weapons/acf_gun/distancehowitzer.wav
diff --git a/sound/weapons/ACF_Gun/distancemortar.wav b/sound/weapons/acf_gun/distancemortar.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/distancemortar.wav
rename to sound/weapons/acf_gun/distancemortar.wav
diff --git a/sound/weapons/acf_gun/grenadelauncher.wav b/sound/weapons/acf_gun/grenadelauncher.wav
new file mode 100644
index 000000000..f11636efc
Binary files /dev/null and b/sound/weapons/acf_gun/grenadelauncher.wav differ
diff --git a/sound/weapons/ACF_Gun/howitzer_fire3.wav b/sound/weapons/acf_gun/howitzer_fire3.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/howitzer_fire3.wav
rename to sound/weapons/acf_gun/howitzer_fire3.wav
diff --git a/sound/weapons/ACF_Gun/howitzer_new2.wav b/sound/weapons/acf_gun/howitzer_new2.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/howitzer_new2.wav
rename to sound/weapons/acf_gun/howitzer_new2.wav
diff --git a/sound/weapons/ACF_Gun/mg_fire1.wav b/sound/weapons/acf_gun/mg_fire1.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/mg_fire1.wav
rename to sound/weapons/acf_gun/mg_fire1.wav
diff --git a/sound/weapons/ACF_Gun/mg_fire2.wav b/sound/weapons/acf_gun/mg_fire2.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/mg_fire2.wav
rename to sound/weapons/acf_gun/mg_fire2.wav
diff --git a/sound/weapons/ACF_Gun/mg_fire3.wav b/sound/weapons/acf_gun/mg_fire3.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/mg_fire3.wav
rename to sound/weapons/acf_gun/mg_fire3.wav
diff --git a/sound/weapons/ACF_Gun/mg_fire4.wav b/sound/weapons/acf_gun/mg_fire4.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/mg_fire4.wav
rename to sound/weapons/acf_gun/mg_fire4.wav
diff --git a/sound/weapons/ACF_Gun/missilefire.wav b/sound/weapons/acf_gun/missilefire.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/missilefire.wav
rename to sound/weapons/acf_gun/missilefire.wav
diff --git a/sound/weapons/ACF_Gun/mortar_fire1.wav b/sound/weapons/acf_gun/mortar_fire1.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/mortar_fire1.wav
rename to sound/weapons/acf_gun/mortar_fire1.wav
diff --git a/sound/weapons/ACF_Gun/mortar_new.wav b/sound/weapons/acf_gun/mortar_new.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/mortar_new.wav
rename to sound/weapons/acf_gun/mortar_new.wav
diff --git a/sound/weapons/ACF_Gun/rac_fire1.wav b/sound/weapons/acf_gun/rac_fire1.wav
similarity index 100%
rename from sound/weapons/ACF_Gun/rac_fire1.wav
rename to sound/weapons/acf_gun/rac_fire1.wav
diff --git a/sound/weapons/acf_gun/rac_fire2.wav b/sound/weapons/acf_gun/rac_fire2.wav
new file mode 100644
index 000000000..734d58208
Binary files /dev/null and b/sound/weapons/acf_gun/rac_fire2.wav differ
diff --git a/sound/weapons/acf_gun/smoke_launch.wav b/sound/weapons/acf_gun/smoke_launch.wav
new file mode 100644
index 000000000..fef553b19
Binary files /dev/null and b/sound/weapons/acf_gun/smoke_launch.wav differ
diff --git a/sound/weapons/AMR/sniper_fire.wav b/sound/weapons/amr/sniper_fire.wav
similarity index 100%
rename from sound/weapons/AMR/sniper_fire.wav
rename to sound/weapons/amr/sniper_fire.wav
diff --git a/sound/weapons/AMR/sniper_reload.wav b/sound/weapons/amr/sniper_reload.wav
similarity index 100%
rename from sound/weapons/AMR/sniper_reload.wav
rename to sound/weapons/amr/sniper_reload.wav
diff --git a/sound/weapons/XM25/xm25_boltback.wav b/sound/weapons/xm25/xm25_boltback.wav
similarity index 100%
rename from sound/weapons/XM25/xm25_boltback.wav
rename to sound/weapons/xm25/xm25_boltback.wav
diff --git a/sound/weapons/XM25/xm25_boltforward.wav b/sound/weapons/xm25/xm25_boltforward.wav
similarity index 100%
rename from sound/weapons/XM25/xm25_boltforward.wav
rename to sound/weapons/xm25/xm25_boltforward.wav
diff --git a/sound/weapons/XM25/xm25_magin.wav b/sound/weapons/xm25/xm25_magin.wav
similarity index 100%
rename from sound/weapons/XM25/xm25_magin.wav
rename to sound/weapons/xm25/xm25_magin.wav
diff --git a/sound/weapons/XM25/xm25_magout.wav b/sound/weapons/xm25/xm25_magout.wav
similarity index 100%
rename from sound/weapons/XM25/xm25_magout.wav
rename to sound/weapons/xm25/xm25_magout.wav