diff --git a/README.MD b/README.MD index c70a3d6d..ebfb98b5 100644 --- a/README.MD +++ b/README.MD @@ -1,4 +1,8 @@ # Armored Combat Framework Extended +[![Discord Invite](https://img.shields.io/discord/580463055595503646?label=Discord&style=flat-square)](https://discord.gg/Y8aEYU6) +[![Linting Status](https://img.shields.io/github/actions/workflow/status/MartyX5555/ACE-Dev/main.yml?branch=master&label=Linter%20Status&style=flat-square)](https://github.com/MartyX5555/ACE-Dev/actions?query=workflow%3AGLuaFixer) +[![Repository Size](https://img.shields.io/github/repo-size/MartyX5555/ACE-Dev?label=Repository%20Size&style=flat-square)](https://github.com/MartyX5555/ACE-Dev) +[![Commit Activity](https://img.shields.io/github/commit-activity/m/MartyX5555/ACE-Dev?label=Commit%20Activity&style=flat-square)](https://github.com/MartyX5555/ACE-Dev/graphs/commit-activity) The Armoured Combat Extended (as known as ACE), is an addon that brings you a realistic combat damage system, a several amount of weapons, like cannons, missiles or bombs and a great amount of engines and gearboxes, so you can build one of the most popular stuff on gmod; *tanks and cars*, although you can build whatever you want. To use this addon, wiremod basic knowledge is required. diff --git a/changelog.txt b/changelog.txt index 7bd781ca..22f55d8d 100644 --- a/changelog.txt +++ b/changelog.txt @@ -639,4 +639,28 @@ r100 - Added a button to restore the removed dupes if you want the dupes back. - Added Type 90 tank into dupes. Credits goes to Doitsu - Tweaked the ACE Sound Replacer Tool a bit more. -- Fixed an issue related to sbox limit with racks. \ No newline at end of file +- Fixed an issue related to sbox limit with racks. + +*r160 +- Added a God-based permission mode. Godded players require damage perms to do damage, ungodded ones dont need it. Courtesy of cheezus +- Added InfMap partial support. Effects and particles are still broken. +- Debris will keep the momentum of the destroyed props. +- Fixed GBU-10 not having the bodygroups being loaded properly. Thank you PsychoDog +- ACE notifications are done via new functions. Courtesy of cheezus +- HESH code has proper penetration functions +- Fixed some small bugs + +*r161 +- added pitch support to guns, racks & radars. +- IRSTs now have Cone input. +- Missile rack custom sounds works on dedicated servers. See workaround for details. +- Safezones added on god based permission mode. By cheezus +- Improved how penetration decals are created. Now double side decals are done. +- Added sound extension basic support to missile racks & radars. Please send your feedback about the noise distance +- Removed "You don't own that entity" message from all the ACE entities +- Fixed a problem related to shells bypassing props under certain conditions. +- Fixed some small issues + +*r162 +- Reverted a change that caused problems with traces. +- Default sound level adjusted to 100%. by Cheezus \ No newline at end of file diff --git a/lua/acf/client/cl_acfmenu_gui.lua b/lua/acf/client/cl_acfmenu_gui.lua index ac0ae462..17df12b4 100644 --- a/lua/acf/client/cl_acfmenu_gui.lua +++ b/lua/acf/client/cl_acfmenu_gui.lua @@ -11,8 +11,33 @@ local Classes = ACF.Classes local ACFEnts = ACF.Weapons -local radarClasses = ACF.Classes.Radar -local radars = ACF.Weapons.Radars +local radarClasses = Classes.Radar +local radars = ACFEnts.Radars + +local MainMenuIcon = "icon16/world.png" +local ItemIcon = "icon16/brick.png" +local ItemIcon2 = "icon16/newspaper.png" + +local function AmmoBuildList( ParentNode, NodeName, AmmoTable ) + + local AmmoNode = ParentNode:AddNode( NodeName, ItemIcon ) + + table.sort(AmmoTable, function(a,b) return a.id < b.id end ) + + for _,AmmoTable in pairs(AmmoTable) do + + local EndNode = AmmoNode: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( ItemIcon2 ) + + end +end function PANEL:Init( ) @@ -22,129 +47,118 @@ function PANEL:Init( ) self:SetTall( ScrH() - 150 ) -- --Weapon Select - self.WeaponSelect = vgui.Create( "DTree", self ) - - -- --Tables definition - self.WeaponData = ACFEnts - + local TreePanel = vgui.Create( "DTree", self ) --[[========================= Table distribution ]]--========================= - self.Classes = Classes + self.GunClasses = {} self.MisClasses = {} self.ModClasses = {} - for ID,Table in pairs(self.Classes) do + local FinalContainer = {} - self.GunClasses[ID] = {} - self.MisClasses[ID] = {} - self.ModClasses[ID] = {} + for ID,Table in pairs(Classes) do - for ClassID,Class in pairs(Table) do + self.GunClasses[ID] = {} + self.MisClasses[ID] = {} + self.ModClasses[ID] = {} - Class.id = ClassID + for ClassID,Class in pairs(Table) do - --Table content for Guns folder - if Class.type == "Gun" then + Class.id = ClassID - --print("Gun detected!") - table.insert(self.GunClasses[ID], Class) + --Table content for Guns folder + if Class.type == "Gun" then - --Table content for Missiles folder - elseif Class.type == "missile" then + --print("Gun detected!") + table.insert(self.GunClasses[ID], Class) - --print("Missile detected!") - table.insert(self.MisClasses[ID], Class) + --Table content for Missiles folder + elseif Class.type == "missile" then - else + --print("Missile detected!") + table.insert(self.MisClasses[ID], Class) - --print("Modded Gun detected!") - table.insert(self.ModClasses[ID], Class) + else + + --print("Modded Gun detected!") + table.insert(self.ModClasses[ID], Class) + + end end + table.sort(self.GunClasses[ID], function(a,b) return a.id < b.id end ) + table.sort(self.MisClasses[ID], function(a,b) return a.id < b.id end ) + table.sort(self.ModClasses[ID], function(a,b) return a.id < b.id end ) + end - table.sort(self.GunClasses[ID], function(a,b) return a.id < b.id end ) - table.sort(self.MisClasses[ID], function(a,b) return a.id < b.id end ) - table.sort(self.ModClasses[ID], function(a,b) return a.id < b.id end ) + for ID,Table in pairs(ACFEnts) do - end + FinalContainer[ID] = {} - self.WeaponDisplay = {} - local WeaponDisplay = ACFEnts + for _,Data in pairs(Table) do + table.insert( FinalContainer[ID], Data ) + end - for ID,Table in pairs(WeaponDisplay) do - self.WeaponDisplay[ID] = {} - for _,Data in pairs(Table) do - table.insert(self.WeaponDisplay[ID], Data) - end + if ID == "Guns" then + table.sort(FinalContainer[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(FinalContainer[ID], function(a,b) return a.id < b.id end ) + 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 ---[[========================= - ACE information folder -]]--========================= + ------------------- ACE information folder ------------------- + - HomeNode = self.WeaponSelect:AddNode( "ACE Main Menu" , "icon16/world.png" ) --Main Menu folder + HomeNode = TreePanel:AddNode( "ACE Main Menu" , MainMenuIcon ) --Main Menu folder HomeNode:SetExpanded(true) HomeNode.mytable = {} HomeNode.mytable.guicreate = (function( _, Table ) ACFHomeGUICreate( Table ) end or nil) HomeNode.mytable.guiupdate = (function( _, Table ) ACFHomeGUIUpdate( Table ) end or nil) function HomeNode:DoClick() - acfmenupanel:UpdateDisplay(self.mytable) + acfmenupanel:UpdateDisplay(self.mytable) end + ------------------- Guns folder ------------------- ---[[========================= - Guns folder -]]--========================= local Guns = HomeNode:AddNode( "Guns" , "icon16/attach.png" ) --Guns folder for _,Class in pairs(self.GunClasses["GunClass"]) do - local SubNode = Guns:AddNode( Class.name or "No Name" , "icon16/brick.png" ) + local SubNode = Guns:AddNode( Class.name or "No Name" , ItemIcon ) - for _, Ent in pairs(self.WeaponDisplay["Guns"]) do - if Ent.gunclass == Class.id then + for _, Ent in pairs(FinalContainer["Guns"]) do + if Ent.gunclass == Class.id then - local EndNode = SubNode:AddNode( Ent.name or "No Name") - EndNode.mytable = Ent + 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 ) + function EndNode:DoClick() + RunConsoleCommand( "acfmenu_type", self.mytable.type ) + acfmenupanel:UpdateDisplay( self.mytable ) + end + + EndNode.Icon:SetImage( "icon16/newspaper.png" ) end - EndNode.Icon:SetImage( "icon16/newspaper.png" ) end end - end + ------------------- Missiles folder ------------------- ---[[========================= - Modded Guns folder -]]--========================= - ---print(table.Count(self.ModClasses)) - - if next(self.ModClasses["GunClass"]) then --this will only load any uncategorized, non official weapon of ace. If they are missiles, Gearboxes or Engines, they will be loaded on missiles, Gearboxes and Engines folder respectively!! - - local Mod = HomeNode:AddNode( "Modded Guns" , "icon16/attach.png") --Modded Guns folder + local Missiles = HomeNode:AddNode( "Missiles" , "icon16/wand.png" ) --Missiles folder - for _,Class in pairs(self.ModClasses["GunClass"]) do + for _,Class in pairs(self.MisClasses["GunClass"]) do - local SubNode = Mod:AddNode( Class.name or "No Name" , "icon16/brick.png" ) + local SubNode = Missiles:AddNode( Class.name or "No Name" , ItemIcon ) - for _, Ent in pairs(self.WeaponDisplay["Guns"]) do + for _, Ent in pairs(FinalContainer["Guns"]) do if Ent.gunclass == Class.id then local EndNode = SubNode:AddNode( Ent.name or "No Name") @@ -156,262 +170,152 @@ function PANEL:Init( ) end EndNode.Icon:SetImage( "icon16/newspaper.png" ) end - end - - end - end ---[[========================= - Missiles folder -]]--========================= - - local Missiles = HomeNode:AddNode( "Missiles" , "icon16/wand.png" ) --Missiles folder - - for _,Class in pairs(self.MisClasses["GunClass"]) do - - local SubNode = Missiles:AddNode( Class.name or "No Name" , "icon16/brick.png" ) - - for _, 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 + ------------------- Ammo folder ------------------- - end - ---[[========================= - Ammo folder -]]--========================= local Ammo = HomeNode:AddNode( "Ammo" , "icon16/box.png" ) --Ammo folder - local AP = Ammo:AddNode("Armor Piercing Rounds", "icon16/brick.png" ) - local HE = Ammo:AddNode("High Explosive Rounds", "icon16/brick.png" ) - local SPECS = Ammo:AddNode("Special Purpose Rounds" , "icon16/brick.png" ) - ---[[========================= - Ammo subfolder AP -]]--========================= - - local APAttribs = list.Get("APRoundTypes") - self.APAttribs = {} - for ID,Table in pairs(APAttribs) do - Table.id = ID - table.insert(self.APAttribs, Table) - end - table.sort(self.APAttribs, function(a,b) return a.id < b.id end ) - - - for _,AmmoTable in pairs(self.APAttribs) do - - local EndNode = AP: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 - ---[[========================= - Ammo subfolder HE -]]--========================= - - local HEAttribs = list.Get("HERoundTypes") - self.HEAttribs = {} - for ID,Table in pairs(HEAttribs) do - Table.id = ID - table.insert(self.HEAttribs, Table) - end - table.sort(self.HEAttribs, function(a,b) return a.id < b.id end ) - - - for _,AmmoTable in pairs(self.HEAttribs) do - - local EndNode = HE: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 - ---[[========================= - Ammo subfolder SPECS -]]--========================= - - local SPECSAttribs = list.Get("SPECSRoundTypes") --local RoundAttribs = list.Get("ACFRoundTypes") - self.SPECSAttribs = {} - for ID,Table in pairs(SPECSAttribs) do - Table.id = ID - table.insert(self.SPECSAttribs, Table) - end - table.sort(self.SPECSAttribs, function(a,b) return a.id < b.id end ) - - - for _,AmmoTable in pairs(self.SPECSAttribs) do - - local EndNode = SPECS: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 + AmmoBuildList( Ammo, "Armor Piercing Rounds", list.Get("APRoundTypes") ) -- AP Content + AmmoBuildList( Ammo, "High Explosive Rounds", list.Get("HERoundTypes") ) -- HE/HEAT Content + AmmoBuildList( Ammo, "Special Purpose Rounds", list.Get("SPECSRoundTypes") ) -- Special Content do + --[[================================================== + Mobility folder + ]]--================================================== - --[[================================================== - Mobility folder - ]]--================================================== - - local Mobility = HomeNode:AddNode( "Mobility" , "icon16/car.png" ) --Mobility folder - local Engines = Mobility:AddNode( "Engines" , "icon16/brick.png" ) - local Gearboxes = Mobility:AddNode( "Gearboxes" , "icon16/brick.png" ) - local FuelTanks = Mobility:AddNode( "Fuel Tanks" , "icon16/brick.png" ) + local Mobility = HomeNode:AddNode( "Mobility" , "icon16/car.png" ) --Mobility folder + local Engines = Mobility:AddNode( "Engines" , ItemIcon ) + local Gearboxes = Mobility:AddNode( "Gearboxes" , ItemIcon ) + local FuelTanks = Mobility:AddNode( "Fuel Tanks" , ItemIcon ) - local EngineCatNodes = {} --Stores all Engine Cats Nodes (V12, V8, I4, etc) - local GearboxCatNodes = {} --Stores all Gearbox Cats Nodes (CVT, Transfer, etc) + local EngineCatNodes = {} --Stores all Engine Cats Nodes (V12, V8, I4, etc) + local GearboxCatNodes = {} --Stores all Gearbox Cats Nodes (CVT, Transfer, etc) - -------------------- Engine folder -------------------- + -------------------- Engine folder -------------------- - --TODO: Do a menu like fueltanks to engines & gearboxes? Would be cleaner. + --TODO: Do a menu like fueltanks to engines & gearboxes? Would be cleaner. - --Creates the engine category - for _, EngineData in pairs(self.WeaponDisplay["Engines"]) do + --Creates the engine category + for _, EngineData in pairs(FinalContainer["Engines"]) do - local category = EngineData.category or "Missing Cat?" + local category = EngineData.category or "Missing Cat?" - if not EngineCatNodes[category] then + if not EngineCatNodes[category] then - local Node = Engines:AddNode(category , "icon16/brick.png") + local Node = Engines:AddNode(category , ItemIcon) - EngineCatNodes[category] = Node + EngineCatNodes[category] = Node + end end - end - --Populates engine categories - for _, EngineData in pairs(self.WeaponDisplay["Engines"]) do + --Populates engine categories + for _, EngineData in pairs(FinalContainer["Engines"]) do - local name = EngineData.name or "Missing Name" - local category = EngineData.category or "" + local name = EngineData.name or "Missing Name" + local category = EngineData.category or "" - if EngineCatNodes[category] then - local Item = EngineCatNodes[category]:AddNode( name, "icon16/brick.png" ) + if EngineCatNodes[category] then + local Item = EngineCatNodes[category]:AddNode( name, ItemIcon ) - function Item:DoClick() - RunConsoleCommand( "acfmenu_type", EngineData.type ) - acfmenupanel:UpdateDisplay( EngineData ) + function Item:DoClick() + RunConsoleCommand( "acfmenu_type", EngineData.type ) + acfmenupanel:UpdateDisplay( EngineData ) + end end end - end - -------------------- Gearbox folder -------------------- + -------------------- Gearbox folder -------------------- - --Creates the gearbox category - for _, GearboxData in pairs(self.WeaponDisplay["Gearboxes"]) do + --Creates the gearbox category + for _, GearboxData in pairs(FinalContainer["Gearboxes"]) do - local category = GearboxData.category + local category = GearboxData.category - if not GearboxCatNodes[category] then + if not GearboxCatNodes[category] then - local Node = Gearboxes:AddNode(category or "Missing?" , "icon16/brick.png") + local Node = Gearboxes:AddNode(category or "Missing?" , ItemIcon) - GearboxCatNodes[category] = Node + GearboxCatNodes[category] = Node + end end - end - --Populates gearbox categories - for _, GearboxData in pairs(self.WeaponDisplay["Gearboxes"]) do + --Populates gearbox categories + for _, GearboxData in pairs(FinalContainer["Gearboxes"]) do - local name = GearboxData.name or "Missing Name" - local category = GearboxData.category or "" + local name = GearboxData.name or "Missing Name" + local category = GearboxData.category or "" - if GearboxCatNodes[category] then - local Item = GearboxCatNodes[category]:AddNode( name, "icon16/brick.png" ) + if GearboxCatNodes[category] then + local Item = GearboxCatNodes[category]:AddNode( name, ItemIcon ) - function Item:DoClick() - RunConsoleCommand( "acfmenu_type", GearboxData.type ) - acfmenupanel:UpdateDisplay( GearboxData ) + function Item:DoClick() + RunConsoleCommand( "acfmenu_type", GearboxData.type ) + acfmenupanel:UpdateDisplay( GearboxData ) + end end end - end - - -------------------- FuelTank folder -------------------- - --Creates the only button to access to fueltank config menu. - for _, FuelTankData in pairs(self.WeaponDisplay["FuelTanks"]) do + -------------------- FuelTank folder -------------------- - function FuelTanks:DoClick() - RunConsoleCommand( "acfmenu_type", FuelTankData.type ) - acfmenupanel:UpdateDisplay( FuelTankData ) - end + --Creates the only button to access to fueltank config menu. + for _, FuelTankData in pairs(FinalContainer["FuelTanks"]) do - break - end + function FuelTanks:DoClick() + RunConsoleCommand( "acfmenu_type", FuelTankData.type ) + acfmenupanel:UpdateDisplay( FuelTankData ) + end + break + end end - do - - --[[================================================== - Sensor folder - ]]--================================================== - - local sensors = HomeNode:AddNode("Sensors" , "icon16/transmit.png") --Sensor folder name - - local antimissile = sensors:AddNode("Anti-Missile Radar" , "icon16/brick.png" ) - local tracking = sensors:AddNode("Tracking Radar", "icon16/brick.png") - local irst = sensors:AddNode("IRST", "icon16/brick.png") - - local nods = {} - - if radarClasses then - for k, v in pairs(radarClasses) do --calls subfolders - if v.type == "Tracking-Radar" then - nods[k] = tracking:AddNode( v.name or "No Name" , "icon16/brick.png" ) - elseif v.type == "Anti-missile" then - nods[k] = antimissile:AddNode( v.name or "No Name" , "icon16/brick.png" ) - elseif v.type == "IRST" then - nods[k] = irst:AddNode( v.name or "No Name" , "icon16/brick.png" ) + --[[================================================== + Sensor folder + ]]--================================================== + + local sensors = HomeNode:AddNode("Sensors" , "icon16/transmit.png") --Sensor folder name + + local antimissile = sensors:AddNode("Anti-Missile Radar" , ItemIcon ) + local tracking = sensors:AddNode("Tracking Radar", ItemIcon) + local irst = sensors:AddNode("IRST", ItemIcon) + + local nods = {} + + if radarClasses then + for k, v in pairs(radarClasses) do --calls subfolders + if v.type == "Anti-missile" then + nods[k] = antimissile:AddNode( v.name or "No Name" , ItemIcon ) + elseif v.type == "Tracking-Radar" then + nods[k] = tracking + elseif v.type == "IRST" then + nods[k] = irst + end end - end - for _, Ent in pairs(radars) do --calls subfolders content + --calls subfolders content + for _, Ent in pairs(radars) do - local curNode = nods[Ent.class] --print(Ent.class) + local curNode = nods[Ent.class] - if curNode then + if curNode then - local EndNode = curNode:AddNode( Ent.name or "No Name" ) - EndNode.mytable = Ent + local EndNode = curNode: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 radar folder - end + function EndNode:DoClick() + RunConsoleCommand( "acfmenu_type", self.mytable.type ) + acfmenupanel:UpdateDisplay( self.mytable ) + end + EndNode.Icon:SetImage( "icon16/newspaper.png" ) + end + end --end radar folder + end end @@ -421,7 +325,7 @@ function PANEL:Init( ) Settings folder ]]--================================================== - local OptionsNode = self.WeaponSelect:AddNode( "Settings" ) --Options folder + local OptionsNode = TreePanel:AddNode( "Settings" ) --Options folder local CLNod = OptionsNode:AddNode("Client" , "icon16/user.png") --Client folder local SVNod = OptionsNode:AddNode("Server", "icon16/cog.png") --Server folder @@ -448,7 +352,7 @@ function PANEL:Init( ) Contact & Support folder ]]--================================================== - local Contact = self.WeaponSelect:AddNode( "Contact Us" , "icon16/feed.png" ) --Options folder + local Contact = TreePanel:AddNode( "Contact Us" , "icon16/feed.png" ) --Options folder Contact.mytable = {} Contact.mytable.guicreate = (function( _, Table ) ContactGUICreate( Table ) end or nil) @@ -459,6 +363,8 @@ function PANEL:Init( ) end + self.WeaponSelect = TreePanel + end function PANEL:UpdateDisplay( Table ) @@ -491,14 +397,6 @@ function PANEL:UpdateDisplay( Table ) end -function PANEL:CreateAttribs() - --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() - --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 @@ -609,25 +507,24 @@ function ACFHomeGUIUpdate( Table ) local versionstring if ACF.CurrentVersion > 0 then - 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 + 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 else - versionstring = "No internet Connection available!" - color = Color(225,0,0,255) + versionstring = "No internet Connection available!" + color = Color(225,0,0,255) end local txt if ACF.CurrentVersion > 0 then - txt = "ACE Is " .. versionstring .. "!\n\n" + txt = "ACE Is " .. versionstring .. "!\n\n" else - txt = versionstring + txt = versionstring end acfmenupanel["CData"]["VersionText"]:SetText(txt) @@ -646,16 +543,11 @@ function ACFChangelogHTTPCallBack(contents) acfmenupanel.Changelog = {} --changelog table for _,String in pairs(Temp) do - - acfmenupanel.Changelog[tonumber(string.sub(String,2,4))] = string.Trim(string.sub(String, 5)) - + acfmenupanel.Changelog[tonumber(string.sub(String,2,4))] = string.Trim(string.sub(String, 5)) end table.SortByKey(acfmenupanel.Changelog,true) - - --print('1.-' .. acfmenupanel.Changelog[100] .. '\n2.-' .. acfmenupanel.Changelog[101] .. '\n3.-' .. acfmenupanel.Changelog[102]) - local Table = {} Table.guicreate = (function( _, Table ) ACFHomeGUICreate( Table ) end or nil) Table.guiupdate = (function( _, Table ) ACFHomeGUIUpdate( Table ) end or nil) @@ -687,6 +579,17 @@ function ACFCLGUICreate() Sub:SizeToContents() acfmenupanel.CustomDisplay:AddItem( Sub ) + local Sounds = vgui.Create( "DForm" ) + Sounds:SetName("Sounds") + + Sounds:CheckBox("Allow Tinnitus Noise", "acf_tinnitus") + Sounds:ControlHelp( "Allows the ear tinnitus effect to be applied when an explosive was detonated too close to your position, improving the inmersion during combat." ) + + Sounds:NumSlider( "Ambient overall sounds", "acf_sound_volume", 0, 100, 0 ) + Sounds:ControlHelp( "Adjusts the volume of ACE sounds like explosions, penetrations, ricochets, etc. Engines and some mechanic sounds are not affected yet." ) + + acfmenupanel.CustomDisplay:AddItem( Sounds ) + local Effects = vgui.Create( "DForm" ) Effects:SetName("Rendering") @@ -711,6 +614,18 @@ function ACFCLGUICreate() end +local function MenuNotifyError() + + local Note = vgui.Create( "DLabel" ) + Note:SetPos( 0, 0 ) + Note:SetColor( Color(10,10,10) ) + Note:SetText("Not available in this moment") + Note:SizeToContents() + acfmenupanel.CustomDisplay:AddItem( Note ) + +end + + --[[========================= Serverside folder content ]]--========================= @@ -719,7 +634,7 @@ function ACFSVGUICreate() --Serverside folder content local ply = LocalPlayer() if not IsValid(ply) then return end if not ply:IsSuperAdmin() then return end - if game.IsDedicated() then ACFSVGUIERROR() return end + if game.IsDedicated() then MenuNotifyError() return end local Server = acfmenupanel["CData"]["Options"] @@ -810,17 +725,6 @@ function ACFSVGUICreate() --Serverside folder content acfmenupanel.CustomDisplay:AddItem( Legal ) end -function ACFSVGUIERROR() - - local Note = vgui.Create( "DLabel" ) - Note:SetPos( 0, 0 ) - Note:SetColor( Color(10,10,10) ) - Note:SetText("Not available in this moment") - Note:SizeToContents() - acfmenupanel.CustomDisplay:AddItem( Note ) - -end - --[[========================= Contact folder content @@ -899,14 +803,13 @@ do if not acfmenupanel.AmmoData then - acfmenupanel.AmmoData = {} - acfmenupanel.AmmoData["Id"] = "10:10:10" --default Ammo dimension on list - acfmenupanel.AmmoData["IdLegacy"] = "Ammo2x4x4" - acfmenupanel.AmmoData["Type"] = "Ammo" - acfmenupanel.AmmoData["Classname"] = acfmenupanel.Classes.GunClass["MG"]["name"] - acfmenupanel.AmmoData["ClassData"] = acfmenupanel.Classes.GunClass["MG"]["id"] - acfmenupanel.AmmoData["Data"] = acfmenupanel.WeaponData["Guns"]["12.7mmMG"]["round"] - + acfmenupanel.AmmoData = {} + acfmenupanel.AmmoData["Id"] = "10:10:10" --default Ammo dimension on list + acfmenupanel.AmmoData["IdLegacy"] = "Ammo2x4x4" + acfmenupanel.AmmoData["Type"] = "Ammo" + acfmenupanel.AmmoData["Classname"] = Classes.GunClass["MG"]["name"] + acfmenupanel.AmmoData["ClassData"] = Classes.GunClass["MG"]["id"] + acfmenupanel.AmmoData["Data"] = ACFEnts["Guns"]["12.7mmMG"]["round"] end if not acfmenupanel.AmmoPanelConfig then @@ -1045,7 +948,7 @@ do local AmmoComboBox = vgui.Create( "DComboBox", CrateOldPanel ) --Every display and slider is placed in the Round table so it gets trashed when selecting a new round type AmmoComboBox:SetSize(acfmenupanel.CustomDisplay:GetWide(), 30) - for Key, Value in pairs( acfmenupanel.WeaponDisplay["Ammo"] ) do + for Key, Value in pairs( ACFEnts.Ammo ) do AmmoComboBox:AddChoice( Value.id , Key ) --Creates the list @@ -1108,7 +1011,7 @@ do local DComboList = {} - for _, GunTable in pairs( acfmenupanel.Classes.GunClass ) do + for _, GunTable in pairs( Classes.GunClass ) do if not table.HasValue( Blacklist, GunTable.id ) then acfmenupanel.CData.ClassSelect:AddChoice( GunTable.name , GunTable.id ) @@ -1124,14 +1027,14 @@ do data = acfmenupanel.CData.ClassSelect:GetOptionData(index) -- Why? - acfmenupanel.AmmoData["Classname"] = acfmenupanel.Classes.GunClass[data]["name"] - acfmenupanel.AmmoData["ClassData"] = acfmenupanel.Classes.GunClass[data]["id"] + acfmenupanel.AmmoData["Classname"] = Classes.GunClass[data]["name"] + acfmenupanel.AmmoData["ClassData"] = Classes.GunClass[data]["id"] acfmenupanel.CData.ClassSelect:SetColor( Color(0,0,0) ) acfmenupanel.CData.CaliberSelect:Clear() - for Key, Value in pairs( acfmenupanel.WeaponDisplay["Guns"] ) do + for Key, Value in pairs( ACFEnts.Guns ) do if acfmenupanel.AmmoData["ClassData"] == Value.gunclass then acfmenupanel.CData.CaliberSelect:AddChoice( Value.id , Key ) @@ -1154,7 +1057,7 @@ do acfmenupanel.CData.CaliberSelect:SetText(acfmenupanel.AmmoData["Data"]["id"] ) - for Key, Value in pairs( acfmenupanel.WeaponDisplay["Guns"] ) do + for Key, Value in pairs( ACFEnts.Guns ) do if acfmenupanel.AmmoData["ClassData"] == Value.gunclass then acfmenupanel.CData.CaliberSelect:AddChoice( Value.id , Key ) diff --git a/lua/acf/client/cl_acfpermission.lua b/lua/acf/client/cl_acfpermission.lua index 764d471e..8d4d8393 100644 --- a/lua/acf/client/cl_acfpermission.lua +++ b/lua/acf/client/cl_acfpermission.lua @@ -34,14 +34,13 @@ net.Receive("ACF_refreshfeedback", function() if success then str = "Successfully updated your ACE damage permissions!" - notify = "NOTIFY_GENERIC" + notify = NOTIFY_GENERIC else str = "Failed to update your ACE damage permissions." - notify = "NOTIFY_ERROR" + notify = NOTIFY_ERROR end - GAMEMODE:AddNotify(str, notify, 7) - + notification.AddLegacy(str, notify, 7) end) diff --git a/lua/acf/client/cl_extension.lua b/lua/acf/client/cl_extension.lua deleted file mode 100644 index c1d1f4a7..00000000 --- a/lua/acf/client/cl_extension.lua +++ /dev/null @@ -1,603 +0,0 @@ - ---Featuring functions which manage the current built in ace sound extension system ---TODO: Refactor all this, making ONE function for every sound event. Using tables here fit better than this - ---NOTE: i would like to have a way of having realtime volume/pitch depending if approaching/going away, ---as having a way to switch sounds between indoor & outdoor zones. They will sound fine, issue it would be when you pass from an area to another when the sound is being played - ---NOTE: For proper doppler effect where pitch/volume is dynamically changed, we need something like soundcreate() instead of ply:emitsound. ---Downside of this, that due to gmod limits, one scripted sound per entity can be used at once. Which idk if it would be good for us. ---We'll have more than one dynamic sound at once :/ weird - -ACE = ACE or {} - ---Defines the delay time caused by the distance between the event and you. Increasing it will increment the required time to hear a distant event -ACE.DelayMultipler = 1 - ---Defines the distance range for close, mid and far sounds. Incrementing it will increase the distances between sounds -ACE.DistanceMultipler = 1 - ---Defines the distance range which sonic cracks will be heard by the player -ACE.CrackDistanceMultipler = 1 - ---Enables/Disables Ear ringing effect. Done for those cases where ringing could be annoying -ACE.EnableTinnitus = 1 - ---Defines the distance where ring ears start to affect to player -ACE.TinnitusZoneMultipler = 1.5 - - -ACE.Sounds = ACE.Sounds or {} -ACE.Sounds.GunTb = {} - ---Entities which should be the only thing to block the sight -ACE.Sounds.LOSWhitelist = { - prop_dynamic = true, - prop_physics = true -} - ---Gets the player's point of view if he's using a camera -function ACE_SGetPOV( ply ) - - if not IsValid(ply) then return false, ply end - local ent = ply - - --Gmod camera POV - if ply:GetViewEntity() ~= ply then - ent = ply:GetViewEntity() - return ent - end - - ACE.Sounds.HookTable = ACE.Sounds.HookTable or hook.GetTable() - - -- wire cam controller support. I would wish not to have a really hardcoded way to make everything consistent but well... - local CameraPos = ACE.Sounds.HookTable["CalcView"]["wire_camera_controller_calcview"] - local ThirdPersonPos = CameraPos and CameraPos() - - ent.aceposoverride = nil - - if ThirdPersonPos and ThirdPersonPos.origin then - ent.aceposoverride = ThirdPersonPos.origin - return ent - end - - return NULL -end - ---Used for those extremely quiet sounds, which should be heard close to the player -function ACE_SInDistance( Pos, Mdist ) - - --Don't start this without a player - local ply = LocalPlayer() - - local entply = ply - - if IsValid(ACE_SGetPOV( ply )) then entply = ACE_SGetPOV( ply ) end - - local plyPos = entply:GetPos() - - local Dist = math.abs((plyPos - Pos):Length()) - - --return true if the distance is lower than the maximum distance - if Dist <= Mdist then return true end - return false - -end - ---Used to see if the player has line of sight with the event -function ACE_SHasLOS( EventPos ) - - local ply = LocalPlayer() - - local plyPos = ply.aceposoverride or ply:GetPos() - local headPos = plyPos + ( not ply:InVehicle() and ( ( ply:Crouching() and Vector(0,0,28) ) or Vector(0,0,64) ) or Vector(0,0,0) ) - - local LOSTr = {} - LOSTr.start = EventPos + Vector(0,0,10) - LOSTr.endpos = headPos - LOSTr.filter = function( ent ) if ( ACE.Sounds.LOSWhitelist[ent:GetClass()] ) then return true end end --Only hits the whitelisted ents - local LOS = util.TraceLine(LOSTr) - - --debugoverlay.Line(EventPos, LOS.HitPos , 5, Color(0,255,255)) - - if not LOS.Hit then return true end - return false -end - -function ACE_SIsInDoor() - - local ply = LocalPlayer() - - local entply = ply - if IsValid(ACE_SGetPOV( ply )) then entply = ACE_SGetPOV( ply ) end - - local plyPos = entply.aceposoverride or entply:GetPos() - - local CeilTr = {} - CeilTr.start = plyPos - CeilTr.endpos = plyPos + Vector(0,0,2000) - CeilTr.filter = {} - CeilTr.mask = MASK_SOLID_BRUSHONLY - CeilTr.mins = vector_origin - CeilTr.maxs = CeilTr.mins - local Ceil = util.TraceHull(CeilTr) - - if Ceil.Hit and Ceil.HitWorld then return true end - return false -end - ---Handles Explosion sounds -function ACEE_SBlast( HitPos, Radius, HitWater, HitWorld ) - - local ply = LocalPlayer() - - local entply = ply - - local count = 1 - local Emitted = false --Was the sound played? - local ide = "ACE_Explosion#" .. math.random(1,100000) - - --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. - if timer.Exists( ide ) then return end - timer.Create( ide , 0.1, 0, function() - - count = count + 1 - - if IsValid(ACE_SGetPOV( ply )) then entply = ACE_SGetPOV( ply ) end - - local plyPos = entply.aceposoverride or entply:GetPos() - local Dist = math.abs((plyPos - HitPos):Length()) - local Volume = 1 / (Dist / 500) * Radius * 0.2 - local Pitch = math.Clamp(1000 / Radius, 25, 130) - local Delay = (Dist / 1500) * ACE.DelayMultipler - - if count > Delay then - - --if its not already emitted - if not Emitted then - - Emitted = true --print('timer has emitted the sound in the time: ' .. count) - - --Ground explosions - if not HitWater then - - --the sound definition. Strings are below - local Sound - - --This defines the distance between areas for close, mid and far sounds - local CloseDist = Radius * 275 * ACE.DistanceMultipler - - --Medium dist will be 4.25x times of closedist. So if closedist is 1000 units, then medium dist will be until 4250 units - local MediumDist = CloseDist * 4.25 - - --this variable fixes the vol for a better volume scale. It's possible to change it depending of the sound area below - local VolFix - local PitchFix - - --Required radius to be considered a small explosion. Less than this the explosion will be considered tiny - local SmallEx = 5 - - --Required radius to be considered a medium explosion - local MediumEx = 10 - - --Required radius to be considered a large explosion - local LargeEx = 20 - - --Required radius to be considered a huge explosion. IDK what thing could pass this, but there is it :) - local HugeEx = 150 - - --TODO: Make a way to use tables instead - --Close distance - if Dist < CloseDist then --NOTE: I KNOW ABOUT THIS CANCEROUS LONG NAME FOR THE STRING, JUST IGNORE FOR THIS TIME. - - if Radius >= HugeEx then - VolFix = 2000000 -- rip your ears - PitchFix = 3 - Sound = ACE.Sounds["Blasts"]["huge"]["close"][math.random(1,#ACE.Sounds["Blasts"]["huge"]["close"])] - elseif Radius >= LargeEx then - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["large"]["close"][math.random(1,#ACE.Sounds["Blasts"]["large"]["close"])] - elseif Radius >= MediumEx then - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["medium"]["close"][math.random(1,#ACE.Sounds["Blasts"]["medium"]["close"])] - elseif Radius >= SmallEx then - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["small"]["close"][math.random(1,#ACE.Sounds["Blasts"]["small"]["close"])] - else - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["tiny"]["close"][math.random(1,#ACE.Sounds["Blasts"]["tiny"]["close"])] - end - - --Medium distance - elseif Dist >= CloseDist and Dist < MediumDist then - - if Radius >= LargeEx then - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["large"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["large"]["mid"])] - elseif Radius >= MediumEx then - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["medium"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["medium"]["mid"])] - elseif Radius >= SmallEx then - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["small"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["small"]["mid"])] - else - VolFix = 8 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["tiny"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["tiny"]["mid"])] - end - - --Far distance - elseif Dist >= MediumDist then - - if Radius >= LargeEx then - VolFix = 17 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["large"]["far"][math.random(1,#ACE.Sounds["Blasts"]["large"]["far"])] - elseif Radius >= MediumEx then - VolFix = 17 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["medium"]["far"][math.random(1,#ACE.Sounds["Blasts"]["medium"]["far"])] - elseif Radius >= SmallEx then - VolFix = 17 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["small"]["far"][math.random(1,#ACE.Sounds["Blasts"]["small"]["far"])] - else - VolFix = 17 - PitchFix = 1 - Sound = ACE.Sounds["Blasts"]["tiny"]["far"][math.random(1,#ACE.Sounds["Blasts"]["tiny"]["far"])] - end - - end - - --Tinnitus function - if ACE.EnableTinnitus and not ply.ACE_HasGodMode then - local TinZone = math.max(Radius * 80, 50) * ACE.TinnitusZoneMultipler - - if Dist <= TinZone and ACE_SHasLOS(HitPos) and entply == ply and not ply.aceposoverride then - timer.Simple(0.01, function() - entply:SetDSP(33, true) - entply:StopSound("acf_other/explosions/ring/tinnitus.mp3") --See if it supress the current tinnitus and creates a new one, from 0. Should stop the HE spam tinnitus - entply:EmitSound("acf_other/explosions/ring/tinnitus.mp3", 75, 100, 1) --Disabled sound - end) - end - --debugoverlay.Sphere(HitPos, TinZone, 15, Color(0,0,255,32), 1) - end - - --If a wall is in front of the player and is indoor, reduces its vol - if not ACE_SHasLOS( HitPos ) and ACE_SIsInDoor() then - --print("Inside of building") - VolFix = VolFix * 0.05 - end - - - - entply:EmitSound( Sound or "", 75, Pitch * PitchFix, Volume * VolFix ) - - --play dirt sounds - if Radius >= SmallEx and HitWorld then - sound.Play(ACE.Sounds["Debris"]["low"]["close"][math.random(1,#ACE.Sounds["Debris"]["low"]["close"])] or "", plyPos + (HitPos - plyPos):GetNormalized() * 64, 80, Pitch * PitchFix, Volume * VolFix / 20) - sound.Play(ACE.Sounds["Debris"]["high"]["close"][math.random(1,#ACE.Sounds["Debris"]["high"]["close"])] or "", plyPos + (HitPos - plyPos):GetNormalized() * 64, 80, (Pitch * PitchFix) / 0.5, Volume * VolFix / 20) - end - - --Underwater Explosions - else - entply:EmitSound( "ambient/water/water_splash" .. math.random(1,3) .. ".wav", 75, math.max(Pitch * 0.75,65), Volume * 0.075 ) - entply:EmitSound( "^weapons/underwater_explode3.wav", 75, math.max(Pitch * 0.75,65), Volume * 0.075 ) - end - end - - timer.Stop( ide ) - timer.Remove( ide ) - end - end ) - -end - ---Handles penetration sounds -function ACE_SPen( HitPos, Velocity, Mass ) - - --Don't start this without a player - local ply = LocalPlayer() - - local entply = ply - - local count = 1 - local Emitted = false --Was the sound played? - local ide = "ACE_Penetration#" .. math.random(1,100000) - - --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. - if timer.Exists( ide ) then return end - timer.Create( ide , 0.1, 0, function() - - count = count + 1 - - if IsValid(ACE_SGetPOV( ply )) then entply = ACE_SGetPOV( ply ) end - - local plyPos = entply.aceposoverride or entply:GetPos() - local Dist = math.abs((plyPos - HitPos):Length()) - local Volume = 1 / (Dist / 500) * Mass / 17.5 - local Pitch = math.Clamp(Velocity * 1, 90, 150) - local Delay = (Dist / 1500) * ACE.DelayMultipler - - if count > Delay then - - if not Emitted then - - Emitted = true - - local Sound = ACE.Sounds["Penetrations"]["large"]["close"][math.random(1,#ACE.Sounds["Penetrations"]["large"]["close"])] or "" - local VolFix = 0.5 - - --If a wall is in front of the player and is indoor, reduces its vol at 50% - if not ACE_SHasLOS( HitPos ) and ACE_SIsInDoor() then - --print("Inside of building") - VolFix = VolFix * 0.5 - end - - entply:EmitSound( Sound or "", 75, Pitch, Volume * VolFix) - - end - - timer.Stop( ide ) - timer.Remove( ide ) - end - end ) -end - ---Handles ricochet sounds -function ACEE_SRico( HitPos, Caliber, Velocity, HitWorld ) - - local ply = LocalPlayer() - - local entply = ply - local count = 1 - local Emitted = false --Was the sound played? - - local ide = "ACE_Ricochet#" .. math.random(1,100000) - - --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. - if timer.Exists( ide ) then return end - timer.Create( ide , 0.1, 0, function() - - count = count + 1 - - if IsValid(ACE_SGetPOV( ply )) then entply = ACE_SGetPOV( ply ) end - - local plyPos = entply.aceposoverride or entply:GetPos() - local Dist = math.abs((plyPos - HitPos):Length()) - local Volume = 1 / (Dist / 500) * Velocity / 130000 - local Pitch = math.Clamp(Velocity * 0.001, 90, 150) - local Delay = (Dist / 1500) * ACE.DelayMultipler - - if count > Delay then - - if not Emitted then --print('timer has emitted the sound in the time: ' .. count) - - Emitted = true - - local Sound = "" - local VolFix = 0 - - if not HitWorld then - - --any big gun above 50mm - Sound = ACE.Sounds["Ricochets"]["large"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["large"]["close"])] - VolFix = 4 - - --50mm guns and below - if Caliber <= 5 then - Sound = ACE.Sounds["Ricochets"]["medium"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["medium"]["close"])] - VolFix = 1 - - --lower than 20mm - if Caliber <= 2 then - Sound = ACE.Sounds["Ricochets"]["small"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["small"]["close"])] - VolFix = 1.25 - end - end - - else - --Small weapons sound - if Caliber <= 2 then - Sound = ACE.Sounds["Ricochets"]["small"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["small"]["close"])] - VolFix = 1.25 - - end - end - - --If a wall is in front of the player and is indoor, reduces its vol at 50% - if not ACE_SHasLOS( HitPos ) and ACE_SIsInDoor() then - --print("Inside of building") - VolFix = VolFix * 0.5 - end - - if Sound ~= "" then - entply:EmitSound( Sound or "" , 75, Pitch, Volume * VolFix ) - end - end - - timer.Stop( ide ) - timer.Remove( ide ) - end - end ) -end - -function ACE_SGunFire( Gun, Sound, Propellant ) - - if not IsValid(Gun) then return end - if not Sound or Sound == "" then return end - - Propellant = math.max(Propellant,50) - - local ply = LocalPlayer() - - local entply = ply - - local count = 1 - local Emitted = false - local ide = "ACEFire#" .. math.random(1,100000) - - local Pos = Gun:GetPos() - local GunId = Gun:EntIndex() -- Using Ids to ensure that code doesnt fuck up if the gun is removed from the map during sound late report. - - --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. - if timer.Exists( ide ) then return end - timer.Create( ide , 0.1, 0, function() - - count = count + 1 - - if IsValid(ACE_SGetPOV( ply )) then entply = ACE_SGetPOV( ply ) end - - local plyPos = entply.aceposoverride or entply:GetPos() - local Dist = math.abs((plyPos - Pos):Length()) - local Volume = 1 / (Dist / 500) * Propellant / 18 - local Delay = (Dist / 1500) * ACE.DelayMultipler - - if count > Delay then - - if not Emitted then - - Emitted = true - - --This defines the distance between areas for close, mid and far sounds - local CloseDist = Propellant * 40 * ACE.DistanceMultipler - - --Medium dist will be 4.25x times of closedist. So if closedist is 1000 units, then medium dist will be until 4250 units - local MediumDist = CloseDist * 4.25 - - --local FarDist = MediumDist * 2 - - --this variable fixes the vol for a better volume scale. Overrided normally - local VolFix = 1 - - --Adjustable Pitch. Overrided normally - local Pitch = 100 - - local SoundData = ACE.GSounds["GunFire"][Sound] - - if SoundData then - - local State = "main" - if Dist >= CloseDist and Dist < MediumDist then - - State = "mid" - elseif Dist >= MediumDist then - - State = "far" - end - - ACE.Sounds.GunTb[GunId] = (ACE.Sounds.GunTb[GunId] or 0) + 1 - - if SoundData[State] then - if ACE.Sounds.GunTb[GunId] > #SoundData[State]["Package"] then ACE.Sounds.GunTb[GunId] = 1 end - - --print("Sequence for Gun: " .. ACE.Sounds.GunTb[GunId] .. " / Total Sounds: " .. #SoundData[State]["Package"]) - - Sound = SoundData[State]["Package"][ACE.Sounds.GunTb[GunId]] - - VolFix = SoundData[State]["Volume"] - Pitch = SoundData[State]["Pitch"] - end - - end - - --If a wall is in front of the player and is indoor, reduces its vol at 50% - if not ACE_SHasLOS( Pos ) and ACE_SIsInDoor() then - --print("Inside of building") - VolFix = VolFix * 0.5 - end - - sound.Play(Sound or "", plyPos + (Pos - plyPos):GetNormalized() * 64, 90, Pitch, Volume * VolFix) --Pos => Gun's pos before to timer. Not possible to use Gun:GetPos() due to risk of gun might not exist at this point. - - end - - timer.Stop( ide ) - timer.Remove( ide ) - end - end ) -end - ---TODO: Leave 5 sounds per caliber type. 22 7.26mm sounds go brrrr -function ACE_SBulletCrack( BulletData, Caliber ) - - local ply = LocalPlayer() - - local entply = ply - - debugoverlay.Cross(BulletData.SimPos, 10, 5, Color(0,0,255)) - - local count = 1 - local Emitted = false --Was the sound played? - - local ide = "ACECrack#" .. math.random(1,100000) - - if timer.Exists( ide ) then return end - timer.Create( ide , 0.1, 0, function() - - count = count + 1 - - if IsValid(ACE_SGetPOV( ply )) then entply = ACE_SGetPOV( ply ) end - - local plyPos = entply.aceposoverride or entply:GetPos() --print(plyPos) - - --Delayed event report. - local CrackPos = BulletData.SimPos - BulletData.SimFlight:GetNormalized() * 5000 - local Dist = math.abs((plyPos - CrackPos):Length()) --print('distance from bullet: ' .. Dist) - local Volume = 10000 / Dist --print('Vol: ' .. Volume) - local Delay = (Dist / 1500) * ACE.DelayMultipler --print('amount to match: ' .. Delay) - - if count > Delay then - - if not Emitted then - - Emitted = true - - --flag this, so we are not playing this sound for this bullet next time - BulletData.CrackCreated = true - - local VolFix = 1 - - --Small arm guns - local Sound = ACE.Sounds["Cracks"]["small"]["close"][math.random(1,#ACE.Sounds["Cracks"]["small"]["close"])] - - --30mm gun and above - if Caliber >= 3 then - Sound = ACE.Sounds["Cracks"]["medium"]["close"][math.random(1,#ACE.Sounds["Cracks"]["medium"]["close"])] - - --above 100mm cannons - if Caliber >= 10 then - Sound = ACE.Sounds["Cracks"]["large"]["close"][math.random(1,#ACE.Sounds["Cracks"]["large"]["close"])] - - --Some fly sounds donĀ“t fit really well. Special case here. - if Caliber >= 20 then - Sound = ACE.Sounds["Cracks"]["large"]["close"][math.random(1,#ACE.Sounds["Cracks"]["large"]["close"])] - VolFix = 0.5 - end - end - end - - --If a wall is in front of the player and is indoor, reduces its vol - if not ACE_SHasLOS( CrackPos ) and ACE_SIsInDoor() then - --print("Inside of building") - VolFix = VolFix * 0.025 - end - - entply:EmitSound( Sound or "" , 75, 100, Volume * VolFix ) - - end - timer.Stop( ide ) - timer.Remove( ide ) - end - end ) -end - ---Coming soon ---function ACE_SBulletImpact() ---end diff --git a/lua/acf/client/cl_soundbase.lua b/lua/acf/client/cl_soundbase.lua new file mode 100644 index 00000000..15fd3b49 --- /dev/null +++ b/lua/acf/client/cl_soundbase.lua @@ -0,0 +1,660 @@ + +--Featuring functions which manage the current built in ace sound extension system +--TODO: Refactor all this, making ONE function for every sound event. Using tables here fit better than this + +--NOTE: i would like to have a way of having realtime volume/pitch depending if approaching/going away, +--as having a way to switch sounds between indoor & outdoor zones. They will sound fine, issue it would be when you pass from an area to another when the sound is being played + +--NOTE: For proper doppler effect where pitch/volume is dynamically changed, we need something like soundcreate() instead of ply:emitsound. +--Downside of this, that due to gmod limits, one scripted sound per entity can be used at once. Which idk if it would be good for us. +--We'll have more than one dynamic sound at once :/ weird + +ACE = ACE or {} + +--Defines the delay time caused by the distance between the event and you. Increasing it will increment the required time to hear a distant event +ACE.DelayMultipler = 1 + +--Defines the distance range for close, mid and far sounds. Incrementing it will increase the distances between sounds +ACE.DistanceMultipler = 1 + +--Defines the distance range which sonic cracks will be heard by the player +ACE.CrackDistanceMultipler = 1 + +--Defines the distance where ring ears start to affect to player +ACE.TinnitusZoneMultipler = 1.5 + +----------- Sound Spectrum Config ----------- + +--Required radius to be considered a small explosion. Less than this the explosion will be considered tiny +ACE.SoundSmallEx = 5 + +--Required radius to be considered a medium explosion +ACE.SoundMediumEx = 10 + +--Required radius to be considered a large explosion +ACE.SoundLargeEx = 20 + +--Required radius to be considered a huge explosion. IDK what thing could pass this, but there is it :) +ACE.SoundHugeEx = 150 + + +ACE.Sounds = ACE.Sounds or {} +ACE.Sounds.GunTb = {} + +--Entities which should be the only thing to block the sight +ACE.Sounds.LOSWhitelist = { + prop_dynamic = true, + prop_physics = true +} + +do + + --Global sound function. In order to be modified by a convar config + --If the Origin is an entity, uses entity:EmitSound( SoundTxt , SoundLevel, Pitch, Volume ) + --If the Origin is a vector Position, uses sound.Play(SoundTxt, Position, SoundLevel, Pitch, Volume) + function ACE_EmitSound( SoundTxt, Origin, SoundLevel, Pitch, Volume ) + + Volume = math.min( Volume, 1 ) + local VolumeConfig = GetConVar("acf_sound_volume"):GetInt() / 100 + + if IsEntity(Origin) and IsValid(Origin) then + Origin:EmitSound( SoundTxt, SoundLevel, Pitch, Volume * VolumeConfig ) + elseif isvector( Origin ) then + sound.Play(SoundTxt, Origin, SoundLevel, Pitch, Volume * VolumeConfig ) + end + end + + --Gets the player's point of view if he's using a camera. Returns the entity input if no external entity is involved. + function ACE_SGetHearingEntity( ply ) + if not IsValid(ply) then return ply end + + ------------------------------- Method 1: Via Camera tool ------------------------------- + if ply:GetViewEntity() ~= ply then + return ply:GetViewEntity() + end + + -------------------------- Method 2: Via Wire Cam Controller ----------------------------- + ACE.Sounds.HookTable = ACE.Sounds.HookTable or hook.GetTable() + if ACE.Sounds.HookTable["CalcView"] then + + ply.aceposoverride = nil + -- wire cam controller support. I would wish not to have a really hardcoded way to make everything consistent but well... + local CameraPos = ACE.Sounds.HookTable["CalcView"]["wire_camera_controller_calcview"] + local ThirdPersonPos = CameraPos and CameraPos() + + if ThirdPersonPos and ThirdPersonPos.origin then + ply.aceposoverride = ThirdPersonPos.origin + return ply + end + end + + return ply + end + + function ACE_GetDistanceTime( Dist ) + return (Dist / 1500) * ACE.DelayMultipler + end + + local function GetHeadPos( ply ) + local plyPos = ply.aceposoverride or ply:GetPos() + local headPos = plyPos + ( not ply:InVehicle() and ( ( ply:Crouching() and Vector(0,0,28) ) or Vector(0,0,64) ) or Vector(0,0,0) ) + return headPos + end + + --Used for those extremely quiet sounds, which should be heard close to the player + function ACE_SInDistance( Pos, Distance ) + + local ply = LocalPlayer() + + local entply = ACE_SGetHearingEntity( ply ) + local plyPos = entply:IsPlayer() and GetHeadPos( ply ) or entply:GetPos() + + --return true if the distance is lower than the maximum distance + if ACE_InDist( plyPos, Pos, Distance ) then return true end + + return false + end + + --Used to see if the player has line of sight with the event + function ACE_SHasLOS( EventPos ) + + local ply = LocalPlayer() + local headPos = GetHeadPos( ply ) + + local LOSTr = {} + LOSTr.start = EventPos + Vector(0,0,10) + LOSTr.endpos = headPos + LOSTr.filter = function( ent ) if ACE.Sounds.LOSWhitelist[ent:GetClass()] then return true end end --Only hits the whitelisted ents + local LOS = util.TraceLine(LOSTr) + + if not LOS.Hit then return true end + return false + end + + function ACE_SIsInDoor() + + local ply = LocalPlayer() + local entply = ACE_SGetHearingEntity( ply ) + local plyPos = entply.aceposoverride or entply:GetPos() + + local CeilTr = {} + CeilTr.start = plyPos + CeilTr.endpos = plyPos + Vector(0,0,2000) + CeilTr.filter = {} + CeilTr.mask = MASK_SOLID_BRUSHONLY + local Ceil = util.TraceLine(CeilTr) + + if Ceil.Hit and Ceil.HitWorld then return true end + return false + end + +end + +do + + --Handles Explosion sounds + function ACE_SBlast( HitPos, Radius, HitWater, HitWorld ) + + local ply = LocalPlayer() + + local count = 1 + local Emitted = false --Was the sound played? + local ide = "ACE_Explosion#" .. math.random(1,100000) + + --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. + if timer.Exists( ide ) then return end + timer.Create( ide , 0.1, 0, function() + + count = count + 1 + + local entply = ACE_SGetHearingEntity( ply ) + + local plyPos = entply.aceposoverride or entply:GetPos() + local Dist = (plyPos - HitPos):Length() + local Volume = 1 / (Dist / 500) * Radius * 0.2 + local Pitch = math.Clamp(1000 / Radius, 25, 130) + local Delay = ACE_GetDistanceTime( Dist ) + + if count > Delay then + + --if its not already emitted + if not Emitted then + + Emitted = true + + --Ground explosions + if not HitWater then + + --the sound definition. Strings are below + local Sound + + --This defines the distance between areas for close, mid and far sounds + local CloseDist = Radius * 275 * ACE.DistanceMultipler + + --Medium dist will be 4.25x times of closedist. So if closedist is 1000 units, then medium dist will be 4250 units + local MediumDist = CloseDist * 4.25 + + --this variable fixes the vol for a better volume scale. It's possible to change it depending of the sound area below + local VolFix + local PitchFix + + --TODO: Make a way to use tables instead + --Close distance + if Dist < CloseDist then --NOTE: I KNOW ABOUT THIS CANCEROUS LONG NAME FOR THE STRING, JUST IGNORE FOR THIS TIME. + + if Radius >= ACE.SoundHugeEx then + VolFix = 2000000 -- rip your ears + PitchFix = 3 + Sound = ACE.Sounds["Blasts"]["huge"]["close"][math.random(1,#ACE.Sounds["Blasts"]["huge"]["close"])] + elseif Radius >= ACE.SoundLargeEx then + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["large"]["close"][math.random(1,#ACE.Sounds["Blasts"]["large"]["close"])] + elseif Radius >= ACE.SoundMediumEx then + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["medium"]["close"][math.random(1,#ACE.Sounds["Blasts"]["medium"]["close"])] + elseif Radius >= ACE.SoundSmallEx then + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["small"]["close"][math.random(1,#ACE.Sounds["Blasts"]["small"]["close"])] + else + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["tiny"]["close"][math.random(1,#ACE.Sounds["Blasts"]["tiny"]["close"])] + end + + --Medium distance + elseif Dist >= CloseDist and Dist < MediumDist then + + if Radius >= ACE.SoundLargeEx then + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["large"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["large"]["mid"])] + elseif Radius >= ACE.SoundMediumEx then + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["medium"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["medium"]["mid"])] + elseif Radius >= ACE.SoundSmallEx then + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["small"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["small"]["mid"])] + else + VolFix = 8 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["tiny"]["mid"][math.random(1,#ACE.Sounds["Blasts"]["tiny"]["mid"])] + end + + --Far distance + elseif Dist >= MediumDist then + + if Radius >= ACE.SoundLargeEx then + VolFix = 17 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["large"]["far"][math.random(1,#ACE.Sounds["Blasts"]["large"]["far"])] + elseif Radius >= ACE.SoundMediumEx then + VolFix = 17 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["medium"]["far"][math.random(1,#ACE.Sounds["Blasts"]["medium"]["far"])] + elseif Radius >= ACE.SoundSmallEx then + VolFix = 17 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["small"]["far"][math.random(1,#ACE.Sounds["Blasts"]["small"]["far"])] + else + VolFix = 17 + PitchFix = 1 + Sound = ACE.Sounds["Blasts"]["tiny"]["far"][math.random(1,#ACE.Sounds["Blasts"]["tiny"]["far"])] + end + + end + + --Tinnitus function + if not ply:HasGodMode() then + local TinZone = math.max(Radius * 80, 50) * ACE.TinnitusZoneMultipler + + if Dist <= TinZone and ACE_SHasLOS(HitPos) and entply == ply and not ply.aceposoverride then + + entply:SetDSP(33, true) + + if GetConVar("acf_tinnitus"):GetInt() == 1 then + + --See if it supress the current tinnitus and creates a new one, from 0. Should stop the HE spam tinnitus + entply:StopSound("acf_other/explosions/ring/tinnitus.mp3") + ACE_EmitSound("acf_other/explosions/ring/tinnitus.mp3", entply, 75, 100, 1 ) + + end + end + --debugoverlay.Sphere(HitPos, TinZone, 15, Color(0,0,255,32), 1) + end + + --If a wall is in front of the player and is indoor, reduces its vol + if not ACE_SHasLOS( HitPos ) and ACE_SIsInDoor() then + --print("Inside of building") + VolFix = VolFix * 0.05 + end + + ACE_EmitSound( Sound or "", entply, 75, Pitch * PitchFix, Volume * VolFix ) + + --play dirt sounds + if Radius >= ACE.SoundSmallEx and HitWorld then + ACE_EmitSound( ACE.Sounds["Debris"]["low"]["close"][math.random(1,#ACE.Sounds["Debris"]["low"]["close"])] or "", plyPos + (HitPos - plyPos):GetNormalized() * 64, 80, Pitch * PitchFix, Volume * VolFix / 20 ) + ACE_EmitSound( ACE.Sounds["Debris"]["high"]["close"][math.random(1,#ACE.Sounds["Debris"]["high"]["close"])] or "", plyPos + (HitPos - plyPos):GetNormalized() * 64, 80, (Pitch * PitchFix) / 0.5, Volume * VolFix / 20 ) + end + + --Underwater Explosions + else + ACE_EmitSound( "ambient/water/water_splash" .. math.random(1,3) .. ".wav", entply, 75, math.max(Pitch * 0.75,65), Volume * 0.075 ) + ACE_EmitSound( "^weapons/underwater_explode3.wav", entply, 75, math.max(Pitch * 0.75,65), Volume * 0.075 ) + end + end + + timer.Stop( ide ) + timer.Remove( ide ) + end + end ) + + end + + --Handles penetration sounds + function ACE_SPenetration( HitPos, Velocity, Mass ) + + --Don't start this without a player + local ply = LocalPlayer() + + local count = 1 + local Emitted = false --Was the sound played? + local ide = "ACE_Penetration#" .. math.random(1,100000) + + --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. + if timer.Exists( ide ) then return end + timer.Create( ide , 0.1, 0, function() + + count = count + 1 + + local entply = ACE_SGetHearingEntity( ply ) + + local plyPos = entply.aceposoverride or entply:GetPos() + local Dist = (plyPos - HitPos):Length() + local Volume = 1 / (Dist / 500) * Mass / 17.5 + local Pitch = math.Clamp(Velocity * 1, 90, 150) + local Delay = ACE_GetDistanceTime( Dist ) + + if count > Delay then + + if not Emitted then + + Emitted = true + + local Sound = ACE.Sounds["Penetrations"]["large"]["close"][math.random(1,#ACE.Sounds["Penetrations"]["large"]["close"])] or "" + local VolFix = 0.5 + + --If a wall is in front of the player and is indoor, reduces its vol at 50% + if not ACE_SHasLOS( HitPos ) and ACE_SIsInDoor() then + --print("Inside of building") + VolFix = VolFix * 0.5 + end + + ACE_EmitSound( Sound, entply, 75, Pitch, Volume * VolFix ) + end + + timer.Stop( ide ) + timer.Remove( ide ) + end + end ) + end + + --Handles ricochet sounds + function ACE_SRicochet( HitPos, Caliber, Velocity, HitWorld ) + + local ply = LocalPlayer() + + local count = 1 + local Emitted = false --Was the sound played? + + local ide = "ACE_Ricochet#" .. math.random(1,100000) + + --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. + if timer.Exists( ide ) then return end + timer.Create( ide , 0.1, 0, function() + + count = count + 1 + + local entply = ACE_SGetHearingEntity( ply ) + + local plyPos = entply.aceposoverride or entply:GetPos() + local Dist = (plyPos - HitPos):Length() + local Volume = 1 / (Dist / 500) * Velocity / 130000 + local Pitch = math.Clamp(Velocity * 0.001, 90, 150) + local Delay = ACE_GetDistanceTime( Dist ) + + if count > Delay then + + if not Emitted then --print('timer has emitted the sound in the time: ' .. count) + + Emitted = true + + local Sound = "" + local VolFix = 0 + + if not HitWorld then + + --any big gun above 50mm + Sound = ACE.Sounds["Ricochets"]["large"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["large"]["close"])] + VolFix = 4 + + --50mm guns and below + if Caliber <= 5 then + Sound = ACE.Sounds["Ricochets"]["medium"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["medium"]["close"])] + VolFix = 1 + + --lower than 20mm + if Caliber <= 2 then + Sound = ACE.Sounds["Ricochets"]["small"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["small"]["close"])] + VolFix = 1.25 + end + end + + else + + --Small weapons sound + if Caliber <= 2 then + Sound = ACE.Sounds["Ricochets"]["small"]["close"][math.random(1,#ACE.Sounds["Ricochets"]["small"]["close"])] + VolFix = 1.25 + + end + end + + --If a wall is in front of the player and is indoor, reduces its vol at 50% + if not ACE_SHasLOS( HitPos ) and ACE_SIsInDoor() then + --print("Inside of building") + VolFix = VolFix * 0.5 + end + + if Sound ~= "" then + ACE_EmitSound( Sound or "", entply, 75, Pitch, Volume * VolFix ) + end + end + + timer.Stop( ide ) + timer.Remove( ide ) + end + end ) + end + + function ACE_SGunFire( Gun, Sound, PitchOverride, Propellant ) + + if not IsValid(Gun) then return end + if not Sound or Sound == "" then return end + + Propellant = math.max(Propellant,50) + + local ply = LocalPlayer() + + local count = 1 + local Emitted = false + local ide = "ACEFire#" .. math.random(1,100000) + + local Pos = Gun:GetPos() -- Getting the position of the emitter now before the emitter ent stops existing. + local GunId = Gun:EntIndex() -- Using Ids to ensure that code doesnt fuck up if the gun is removed from the map during sound late report. + + --Still it's possible to saturate this, prob you will need to be lucky to get the SAME id in both cases. + if timer.Exists( ide ) then return end + timer.Create( ide , 0.1, 0, function() + + count = count + 1 + + local entply = ACE_SGetHearingEntity( ply ) + + local plyPos = entply.aceposoverride or entply:GetPos() + local Dist = (plyPos - Pos):Length() + local Volume = 1 / (Dist / 500) * Propellant / 18 + local Delay = ACE_GetDistanceTime( Dist ) + + if count > Delay then + + if not Emitted then + + Emitted = true + + --This defines the distance between areas for close, mid and far sounds + local CloseDist = Propellant * 40 * ACE.DistanceMultipler + + --Medium dist will be 4.25x times of closedist. So if closedist is 1000 units, then medium dist will be 4250 units + local MediumDist = CloseDist * 4.25 + + --local FarDist = MediumDist * 2 + + --this variable fixes the vol for a better volume scale. Overrided normally + local VolFix = 1 + + --Adjustable Pitch. Overrided normally + local Pitch = 100 + + local SoundData = ACE.GSounds["GunFire"][Sound] + + if SoundData then + + local State = "main" + if Dist >= CloseDist and Dist < MediumDist then + + State = "mid" + elseif Dist >= MediumDist then + + State = "far" + end + + ACE.Sounds.GunTb[GunId] = (ACE.Sounds.GunTb[GunId] or 0) + 1 + + if SoundData[State] then + if ACE.Sounds.GunTb[GunId] > #SoundData[State]["Package"] then + ACE.Sounds.GunTb[GunId] = 1 + end + + Sound = SoundData[State]["Package"][ACE.Sounds.GunTb[GunId]] + VolFix = SoundData[State]["Volume"] + Pitch = SoundData[State]["Pitch"] + end + + else + Pitch = PitchOverride + end + + --If a wall is in front of the player and is indoor, reduces its vol at 50% + if not ACE_SHasLOS( Pos ) and ACE_SIsInDoor() then + --print("Inside of building") + VolFix = VolFix * 0.5 + end + + --Pos => Gun's pos before to timer. Not possible to use Gun:GetPos() due to risk of gun might not exist at this point. + ACE_EmitSound( Sound or "", plyPos + (Pos - plyPos):GetNormalized() * 64, 90, Pitch, Volume * VolFix ) + + end + + timer.Stop( ide ) + timer.Remove( ide ) + end + end ) + end + + --TODO: Leave 5 sounds per caliber type. 22 7.26mm sounds go brrrr + function ACE_SBulletCrack( BulletData, Caliber ) + + debugoverlay.Cross(BulletData.SimPos, 10, 5, Color(0,0,255)) + + local ply = LocalPlayer() + local count = 1 + local Emitted = false --Was the sound played? + + local ide = "ACECrack#" .. math.random(1,100000) + + --flag this, so we are not playing this sound for this bullet next time + BulletData.CrackCreated = true + + if timer.Exists( ide ) then return end + timer.Create( ide , 0.1, 0, function() + + count = count + 1 + + local entply = ACE_SGetHearingEntity( ply ) + local plyPos = entply.aceposoverride or entply:GetPos() --print(plyPos) + + --Delayed event report. + local CrackPos = BulletData.SimPos - BulletData.SimFlight:GetNormalized() * 5000 + local Dist = (plyPos - CrackPos):Length() + local Volume = 10000 / Dist + local Delay = ACE_GetDistanceTime( Dist ) + + if count > Delay then + + if not Emitted then + + Emitted = true + + local VolFix = 0.1 + + --Small arm guns + local Sound = ACE.Sounds["Cracks"]["small"]["close"][math.random(1,#ACE.Sounds["Cracks"]["small"]["close"])] + + --30mm gun and above + if Caliber >= 3 then + Sound = ACE.Sounds["Cracks"]["medium"]["close"][math.random(1,#ACE.Sounds["Cracks"]["medium"]["close"])] + + --above 100mm cannons + if Caliber >= 10 then + Sound = ACE.Sounds["Cracks"]["large"]["close"][math.random(1,#ACE.Sounds["Cracks"]["large"]["close"])] + VolFix = 1 + + + --Some fly sounds donĀ“t fit really well. Special case here. + if Caliber >= 20 then + Sound = ACE.Sounds["Cracks"]["large"]["close"][math.random(1,#ACE.Sounds["Cracks"]["large"]["close"])] + VolFix = 0.5 + end + end + end + + --If a wall is in front of the player and is indoor, reduces its vol + if not ACE_SHasLOS( CrackPos ) and ACE_SIsInDoor() then + --print("Inside of building") + VolFix = VolFix * 0.025 + end + + ACE_EmitSound( Sound or "" , entply, 75, 100, Volume * VolFix ) + end + timer.Stop( ide ) + timer.Remove( ide ) + end + end ) + end + + --For any miscellaneous sound. BaseDistVolume is the Max dist where Volume will be 1. The volume will start losing dbs beyond this distance. In Units. + function ACE_SimpleSound( Sound, Origin, Pitch, BaseDistVolume ) + + local ply = LocalPlayer() + local count = 1 + local Emitted = false --Was the sound played? + + local ide = "ACESimpleSound#" .. math.random(1,100000) + + if timer.Exists( ide ) then return end + timer.Create( ide , 0.1, 0, function() + + count = count + 1 + + local entply = ACE_SGetHearingEntity( ply ) + local plyPos = entply.aceposoverride or entply:GetPos() + + --Delayed event report. + local Dist = (plyPos - Origin):Length() + local Delay = ACE_GetDistanceTime( Dist ) + local Volume = BaseDistVolume / Dist + + if count > Delay then + + if not Emitted then + + Emitted = true + + local VolFix = 1 + + --If a wall is in front of the player and is indoor, reduces its vol + if not ACE_SHasLOS( Origin ) and ACE_SIsInDoor() then + VolFix = VolFix * 0.025 + end + + ACE_EmitSound( Sound or "" , plyPos + (Origin - plyPos):GetNormalized() * 64, 100, Pitch, Volume * VolFix ) + end + timer.Stop( ide ) + timer.Remove( ide ) + end + end ) + + end + + --Coming soon + --function ACE_SBulletImpact() + --end + +end + + diff --git a/lua/acf/server/permissionmodes/acf_pmode_battle.lua b/lua/acf/server/permissionmodes/acf_pmode_battle.lua index ce32b0c7..2dde3ae6 100644 --- a/lua/acf/server/permissionmodes/acf_pmode_battle.lua +++ b/lua/acf/server/permissionmodes/acf_pmode_battle.lua @@ -35,29 +35,23 @@ local ShouldDisableNoclip = false Return: boolean true if the entity should be damaged, false if the entity should be protected from the damage. ----]] -local function modepermission(_, attacker, ent) +local function modepermission(owner, attacker, ent) local szs = perms.Safezones if szs then local entpos = ent:GetPos() local attpos = attacker:GetPos() + local ownerid = owner:SteamID() + local attackerid = attacker:SteamID() + local ownerperms = perms.GetDamagePermissions(ownerid) - if perms.IsInSafezone(entpos) or perms.IsInSafezone(attpos) then return false end + if (perms.IsInSafezone(entpos) or perms.IsInSafezone(attpos)) and not ownerperms[attackerid] then return false end end return true end - -function tellPlyAboutZones(ply, zone) - 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 @@ -66,7 +60,6 @@ end hook.Add( "PlayerNoClip", "ACF_DisableNoclipPressInBattle", DisableNoclipPressInBattle ) - local function modethink() for _, ply in pairs(player.GetAll()) do --print(ply:GetPos(), perms.IsInSafezone(ply:GetPos())) @@ -94,4 +87,4 @@ local function modethink() end -perms.RegisterMode(modepermission, modename, modedescription, false, modethink) +perms.RegisterMode(modepermission, modename, modedescription, false, modethink, nil, true) diff --git a/lua/acf/server/permissionmodes/acf_pmode_godbased.lua b/lua/acf/server/permissionmodes/acf_pmode_godbased.lua new file mode 100644 index 00000000..a8ae8feb --- /dev/null +++ b/lua/acf/server/permissionmodes/acf_pmode_godbased.lua @@ -0,0 +1,54 @@ +--[[ + ACF Permission mode: God based + This mode allows non-godded players to damage the entities of all other non-godded players. + When in godmode, players can only damage their own entities, and entities of players who have given damage permissions. +]] + +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 + +local modename = "godbased" +local modedescription = "Players without godmode can damage anyone else's entities whose owners are not in godmode." + +--[[ + 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 IsValid(ent) then return false end + + local ownerid = owner:SteamID() + local attackerid = attacker:SteamID() + local ownerperms = perms.GetDamagePermissions(ownerid) + + if perms.Safezones then + local entpos = ent:GetPos() + local attpos = attacker:GetPos() + + if (perms.IsInSafezone(entpos) or perms.IsInSafezone(attpos)) and not ownerperms[attackerid] then return false end + end + + if ent:IsPlayer() or ent:IsNPC() then + return true + end + + local godOwner = owner:HasGodMode() + local godInflictor = attacker:HasGodMode() + + if godOwner then + return ownerperms[attackerid] and true or false + else + return not godInflictor + end + + return false +end + +perms.RegisterMode(modepermission, modename, modedescription, false, nil, DefaultPermission, true) diff --git a/lua/acf/server/sv_acfballistics.lua b/lua/acf/server/sv_acfballistics.lua index 1c3e2776..df4aaabe 100644 --- a/lua/acf/server/sv_acfballistics.lua +++ b/lua/acf/server/sv_acfballistics.lua @@ -113,14 +113,16 @@ function ACF_CheckClips( Ent, HitPos ) 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 --Since tracehull/traceline transition during impacts, this can be 0 with no issues + + local ClipData = Ent.ClipData[i] + + normal = Ent:LocalToWorldAngles(ClipData.n):Forward() + origin = Ent:LocalToWorld(Ent:OBBCenter()) + normal * ClipData.d + --debugoverlay.BoxAngles( origin, Vector(0,-24,-24), Vector(1,24,24), Ent:LocalToWorldAngles(ClipData["n"]), 15, Color(255,0,0,32) ) + if not ClipData.physics and normal:Dot((origin - HitPos):GetNormalized()) > 0 then return true end --Since tracehull/traceline transition during impacts, this can be 0 with no issues end return false - end do @@ -212,17 +214,16 @@ do --if our shell hits visclips, convert the tracehull on traceline. if ACF_CheckClips( FlightRes.Entity, FlightRes.HitPos ) then - FlightTr.maxs = vector_origin - FlightTr.mins = -FlightTr.maxs - -- trace result is stored in supplied output FlightRes (at top of file) - util.TraceHull(FlightTr) + util.TraceLine(FlightTr) -- if our traceline doesnt detect anything after conversion, revert it to tracehull again. This should fix the 1 in 1 billon issue. if not FlightRes.HitNonWorld then - util.TraceHull(FlightTr) - + -- The traceline function overrides the mins/maxs. So i must redefine them again here. + FlightTr.maxs = Vector(TROffset, TROffset, TROffset) + FlightTr.mins = -FlightTr.maxs + util.TraceHull(FlightTr) end end diff --git a/lua/acf/server/sv_acfbase.lua b/lua/acf/server/sv_acfbase.lua index 241f8ae8..d556c610 100644 --- a/lua/acf/server/sv_acfbase.lua +++ b/lua/acf/server/sv_acfbase.lua @@ -248,22 +248,15 @@ function ACF_VehicleDamage(Entity, Energy, FrArea, Angle, Inflictor, _, Gun, Typ if HitRes.Damage ~= HitRes.Damage then HitRes.Damage = 0 end if validd then - local dmg = 40 - - if Type == "Spall" then - dmg = 40 - --print(HitRes.Damage * dmg) - end - Driver:TakeDamage( HitRes.Damage * dmg , Inflictor, Gun ) end HitRes.Kill = false if HitRes.Damage >= Entity.ACF.Health then --Drivers will no longer survive seat destruction - if validd then - Driver:Kill() - end + if validd then + Driver:Kill() + end HitRes.Kill = true else Entity.ACF.Health = Entity.ACF.Health - HitRes.Damage @@ -497,4 +490,45 @@ function ACE_CreateLinkRope( Pos, Ent1, LPos1, Ent2, LPos2 ) return rope +end + +local WireTable = { "gmod_wire_adv_pod", "gmod_wire_pod", "gmod_wire_keyboard", "gmod_wire_joystick", "gmod_wire_joystick_multi" } + +function ACE_GetWeaponUser( Weapon, 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 ACE_GetWeaponUser( Weapon, inp.Inputs.Fire.Src ) + elseif inp.Inputs.Shoot then + return ACE_GetWeaponUser( Weapon, inp.Inputs.Shoot.Src ) + elseif inp.Inputs then + for _,v in pairs(inp.Inputs) do + if v.Src and table.HasValue(WireTable, v.Src:GetClass()) then + return ACE_GetWeaponUser( Weapon, v.Src ) + end + end + end + end + return inp.Owner or inp:CPPIGetOwner() + end \ No newline at end of file diff --git a/lua/acf/server/sv_acfdamage.lua b/lua/acf/server/sv_acfdamage.lua index 0694fde9..81fd0d79 100644 --- a/lua/acf/server/sv_acfdamage.lua +++ b/lua/acf/server/sv_acfdamage.lua @@ -9,28 +9,28 @@ local TraceInit = { output = TraceRes } --Used for filter certain undesired ents inside of HE processing ACF.HEFilter = { - gmod_wire_hologram = true, - starfall_hologram = true, - prop_vehicle_crane = true, - prop_dynamic = true, - ace_debris = true, - sent_tanktracks_legacy = true, - sent_tanktracks_auto = true, - ace_flares = true + gmod_wire_hologram = true, + starfall_hologram = true, + prop_vehicle_crane = true, + prop_dynamic = true, + ace_debris = true, + sent_tanktracks_legacy = true, + sent_tanktracks_auto = true, + ace_flares = true } --Used for tracebug HE workaround ACE.CritEnts = { - acf_gun = true, - acf_ammo = true, - acf_engine = true, - acf_gearbox = true, - acf_fueltank = true, - acf_rack = true, - acf_missile = true, - ace_missile_swep_guided = true, - prop_vehicle_prisoner_pod = true, - gmod_wire_gate = true + acf_gun = true, + acf_ammo = true, + acf_engine = true, + acf_gearbox = true, + acf_fueltank = true, + acf_rack = true, + acf_missile = true, + ace_missile_swep_guided = true, + prop_vehicle_prisoner_pod = true, + gmod_wire_gate = true } --I don't want HE processing every ent that it has in range @@ -242,6 +242,7 @@ function ACF_HE( Hitpos , _ , FillerMass, FragMass, Inflictor, NoOcc, Gun ) end if not (Occ.Hit and Occ.Entity:EntIndex() ~= Tar:EntIndex()) and not (not Occ.Hit and NewHitpos ~= NewHitat) then + BlastRes = ACF_Damage ( Tar , Blast , AreaAdjusted , 0 , Inflictor , 0 , Gun , "HE" ) FragRes = ACF_Damage ( Tar , FragKE , FragArea * FragHit , 0 , Inflictor , 0, Gun, "Frag" ) @@ -859,13 +860,9 @@ local function ACF_KillChildProps( Entity, BlastPos, Energy ) -- can't use #table or :count() because of ent indexing... count = count + 1 end - end - - end - -- HE kill the children of this ent, instead of disappearing them by removing parent if count > 0 then @@ -885,12 +882,9 @@ local function ACF_KillChildProps( Entity, BlastPos, Energy ) constraint.RemoveAll( child ) child:Remove() - - end end - -- explode stuff last, so we don't re-process all that junk again in a new explosion if next( boom ) then @@ -901,7 +895,6 @@ local function ACF_KillChildProps( Entity, BlastPos, Energy ) child.Exploding = true ACF_ScaledExplosion( child ) -- explode any crates that are getting removed - end end end @@ -946,15 +939,14 @@ function ACF_HEKill( Entity , HitVector , Energy , BlastPos ) phys:SetDragCoefficient( -50 ) phys:SetMass( physent:GetMass() ) - phys:ApplyForceOffset( HitVector:GetNormalized() * Energy * 2, Debris:GetPos() + VectorRand() * 10 ) + phys:SetVelocity( ACF_GetPhysicalParent( Entity ):GetVelocity() ) + phys:ApplyForceOffset( HitVector:GetNormalized() * Energy * 2, Debris:WorldSpaceCenter() + VectorRand() * 10 ) end return Debris - end - function ACF_APKill( Entity , HitVector , Power ) -- kill the children of this ent, instead of disappearing them from removing parent @@ -990,11 +982,12 @@ function ACF_APKill( Entity , HitVector , Power ) if phys:IsValid() and physent:IsValid() then phys:SetDragCoefficient( -50 ) phys:SetMass( physent:GetMass() ) - phys:ApplyForceOffset( HitVector:GetNormalized() * Power * 100, Debris:GetPos() + VectorRand() * 10 ) + phys:SetVelocity( ACF_GetPhysicalParent( Entity ):GetVelocity() ) + phys:ApplyForceOffset( HitVector:GetNormalized() * Power * 100, Debris:WorldSpaceCenter() + VectorRand() * 10 ) + end return Debris - end do @@ -1010,30 +1003,30 @@ do local HEWeight local ExplodePos = {} - local MaxGroup = ACF.ScaledEntsMax -- Max number of ents to be cached. Reducing this value will make explosions more realistic at the cost of more explosions = lag - local MaxHE = ACF.ScaledHEMax -- Max amount of HE to be cached. This is useful when we dont want nukes being created by large amounts of clipped ammo. + local MaxGroup = ACF.ScaledEntsMax -- Max number of ents to be cached. Reducing this value will make explosions more realistic at the cost of more explosions = lag + local MaxHE = ACF.ScaledHEMax -- Max amount of HE to be cached. This is useful when we dont want nukes being created by large amounts of clipped ammo. - local Inflictor = ent.Inflictor or nil - local Owner = CPPI and ent:CPPIGetOwner() or NULL + local Inflictor = ent.Inflictor or nil + local Owner = CPPI and ent:CPPIGetOwner() or NULL if ent:GetClass() == "acf_fueltank" then - local Fuel = ent.Fuel or 0 - local Capacity = ent.Capacity or 0 - local Type = ent.FuelType or "Petrol" + local Fuel = ent.Fuel or 0 + local Capacity = ent.Capacity or 0 + local Type = ent.FuelType or "Petrol" HEWeight = ( math.min( Fuel, Capacity ) / ACF.FuelDensity[Type] ) * FuelExplosionScale else - local HE = ent.BulletData.FillerMass or 0 - local Propel = ent.BulletData.PropMass or 0 - local Ammo = ent.Ammo or 0 + local HE = ent.BulletData.FillerMass or 0 + local Propel = ent.BulletData.PropMass or 0 + local Ammo = ent.Ammo or 0 HEWeight = ( ( HE + Propel * ( ACF.PBase / ACF.HEPower ) ) * Ammo ) * AmmoExplosionScale end - local Radius = ACE_CalculateHERadius( HEWeight ) - local Pos = ent:LocalToWorld(ent:OBBCenter()) + local Radius = ACE_CalculateHERadius( HEWeight ) + local Pos = ent:LocalToWorld(ent:OBBCenter()) table.insert(ExplodePos, Pos) @@ -1065,9 +1058,9 @@ do local Hitat = Found:NearestPoint( Pos ) local Occlusion = {} - Occlusion.start = Pos - Occlusion.endpos = Hitat + (Hitat-Pos):GetNormalized() * 100 - Occlusion.filter = Filter + Occlusion.start = Pos + Occlusion.endpos = Hitat + (Hitat-Pos):GetNormalized() * 100 + Occlusion.filter = Filter local Occ = util.TraceLine( Occlusion ) --Filters any ent which blocks the trace. @@ -1087,18 +1080,18 @@ do if Found:GetClass() == "acf_fueltank" then - local Fuel = Found.Fuel or 0 - local Capacity = Found.Capacity or 0 - local Type = Found.FuelType or "Petrol" + local Fuel = Found.Fuel or 0 + local Capacity = Found.Capacity or 0 + local Type = Found.FuelType or "Petrol" FoundHEWeight = ( math.min( Fuel, Capacity ) / ACF.FuelDensity[Type] ) * FuelExplosionScale else if Found.RoundType == "Refill" then Found:Remove() continue end - local HE = Found.BulletData.FillerMass or 0 - local Propel = Found.BulletData.PropMass or 0 - local Ammo = Found.Ammo or 0 + local HE = Found.BulletData.FillerMass or 0 + local Propel = Found.BulletData.PropMass or 0 + local Ammo = Found.Ammo or 0 FoundHEWeight = ( ( HE + Propel * ( ACF.PBase / ACF.HEPower)) * Ammo ) * AmmoExplosionScale end @@ -1107,10 +1100,10 @@ do HEWeight = HEWeight + FoundHEWeight - Found.IsExplosive = false + Found.IsExplosive = false Found.DamageAction = false - Found.KillAction = false - Found.Exploding = true + Found.KillAction = false + Found.Exploding = true table.insert( Filter,Found ) table.remove( CExplosives,i ) @@ -1123,9 +1116,7 @@ do else Occ.Entity:Ignite( 120, HEWeight / 10 ) end - end - end end @@ -1180,3 +1171,5 @@ function ACE_CalculateHERadius( HEWeight ) local Radius = HEWeight ^ 0.33 * 8 * 39.37 return Radius end +-- + diff --git a/lua/acf/server/sv_acfpermission.lua b/lua/acf/server/sv_acfpermission.lua index e7849226..401aec8b 100644 --- a/lua/acf/server/sv_acfpermission.lua +++ b/lua/acf/server/sv_acfpermission.lua @@ -14,6 +14,7 @@ this.Player = {} this.Modes = {} this.ModeDescs = {} this.ModeThinks = {} +this.NotifySafezones = {} --TODO: convar this local mapSZDir = "acf/safezones/" @@ -125,6 +126,11 @@ hook.Add( "Initialize", "ACF_LoadSafesForMap", function() end end ) +hook.Add("ACF_PlayerChangedZone", "ACF_TellPlyAboutSafezoneBattle", function(ply, zone) + if not this.NotifySafezones[table.KeyFromValue(this.Modes, this.DamagePermission)] then return end + + ACE_SendMsg(ply, zone and Color(0, 255, 0) or Color(255, 0, 0), "You have entered the " .. (zone and zone .. " safezone." or "battlefield!")) +end) local plyzones = {} hook.Add("Think", "ACF_DetectSZTransition", function() @@ -354,7 +360,7 @@ concommand.Add( "ACF_SetDefaultPermissionMode", function(ply, _, args) for _, 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 .. "!\")") + ACE_SendMsg(v, Color(255, 0, 0), "Default permission mode for " .. game.GetMap() .. " has been set to " .. mode .. "!") end end @@ -399,7 +405,7 @@ local function tellPlysAboutDPMode(mode, oldmode) if mode == oldmode then return end for _, v in pairs(player.GetAll()) do - v:SendLua("chat.AddText(Color(255,0,0),\"Damage protection has been changed to " .. mode .. " mode!\")") + ACE_SendMsg(v, Color(255,0,0), "Damage protection has been changed to " .. mode .. " mode!") end end hook.Add("ACF_ProtectionModeChanged", "ACF_TellPlysAboutDPMode", tellPlysAboutDPMode) @@ -424,11 +430,12 @@ function this.IsInSafezone(pos) return false end -function this.RegisterMode(mode, name, desc, default, think, defaultaction) +function this.RegisterMode(mode, name, desc, default, think, defaultaction, notifysafezones) this.Modes[name] = mode this.ModeDescs[name] = desc this.ModeThinks[name] = think or function() end + this.NotifySafezones[name] = notifysafezones or false this.DefaultCanDamage = defaultaction or false print("[ACE | INFO]- Registered damage permission mode \"" .. name .. "\"!") @@ -457,6 +464,7 @@ function this.CanDamage(_, Entity, _, _, _, Inflictor, _, _) --Disables protection if either CPPI is unexistent or has been disabled via convar. local DP = GetConVar("acf_enable_dp"):GetInt() if not CPPI or DP == 0 then return true end + if Entity.DamageOwner then return true end -- This value is normally used by entities meant to be destroyed by everyone. local owner = Entity:CPPIGetOwner() --entity to attack. Gets the attacked entity's owner @@ -594,8 +602,8 @@ net.Receive("ACF_dmgfriends", function(_, ply) local note = v and "given you" or "removed your" local MsgNote = v and "given" or "removed" - --Msg("Sending", targ, " ", note, "\n") - targ:SendLua(string.format("GAMEMODE:AddNotify(%q,%s,7)", ply:Nick() .. " has " .. note .. " permission to damage their objects with ACE!", "NOTIFY_GENERIC")) + + ACE_SendNotification(targ, ply:Nick() .. " has " .. note .. " permission to damage their objects with ACE!") print("[ACE | INFO]- The user " .. ply:Nick() .. " has " .. MsgNote .. " permissions to damage objects with ACE " .. (v and "to" or "from") .. " " .. ((targ == ply) and "himself" or targ:Nick())) end end diff --git a/lua/acf/server/sv_contraption.lua b/lua/acf/server/sv_contraption.lua index c93bd783..adcc4145 100644 --- a/lua/acf/server/sv_contraption.lua +++ b/lua/acf/server/sv_contraption.lua @@ -1,13 +1,15 @@ --i'll leave almost everything ready so they can be exported to acf-3 in some near future --print("[ACE | INFO]- Loading Contraption System. . .") --ACE = ACE or {} -ACE.contraptionEnts = {} --table which will have all registered ents -ACE.radarEntities = {} --for tracking radar usage -ACE.radarIDs = {} --ID radar purpose -ACE.ECMPods = {} --ECM usage -ACE.Opticals = {} --GLATGM optical computers -ACE.Explosives = {} --Explosive entities like ammocrates & fueltanks go here -ACE.Debris = {} --Debris count +ACE.contraptionEnts = {} --table which will have all registered ents +ACE.radarEntities = {} --for tracking radar usage +ACE.radarIDs = {} --ID radar purpose +ACE.ECMPods = {} --ECM usage +ACE.Opticals = {} --GLATGM optical computers +ACE.Explosives = {} --Explosive entities like ammocrates & fueltanks go here +ACE.Debris = {} --Debris count +ACE.Mines = ACE.Mines or {} +ACE.MineOwners = ACE.MineOwners or {} -- We want to develop without losing any data inside of this. --list of classname ents which should be added to the contraption ents. local AllowedEnts = { @@ -80,101 +82,103 @@ hook.Add("OnEntityCreated", "ACE_EntRegister", function(Ent) end -- Finally, include the whitelisted entity to the main table ( contraptionEnts ) - if not Ent:GetParent():IsValid() then + if not IsValid(Ent:GetParent()) then table.insert(ACE.contraptionEnts, Ent) --print("[ACE | INFO]- an entity ' .. Ent:GetClass() .. ' has been registered!") --print('Total Ents registered count: ' .. table.Count( ACE.contraptionEnts )) end elseif Ent:GetClass() == "ace_debris" then table.insert(ACE.Debris, Ent) --print('Adding - Count: ' .. #ACE.Debris) + elseif Ent:GetClass() == "ace_mine" then + table.insert(ACE.Mines, Ent) print("Adding - Count: " .. #ACE.Mines) end end) -- Remove any entity of the Contraption List that has been removed from map hook.Add("EntityRemoved", "ACE_EntRemoval", function(Ent) + --Assuming that our table has whitelisted ents if AllowedEnts[Ent:GetClass()] then - for i = 1, #ACE.contraptionEnts do - --check if it's valid - if not IsValid(ACE.contraptionEnts[i]) or not IsValid(Ent) then continue end - local MEnt = ACE.contraptionEnts[i] + + for i, ent in ipairs(ACE.contraptionEnts) do + if not IsValid(ent) or not IsValid(Ent) then continue end -- Remove this ECM from list if deleted if Ent:GetClass() == "ace_ecm" then - for i = 1, table.Count(ACE.ECMPods) do - if ACE.ECMPods[i]:IsValid() and Ent:IsValid() then - local ECM = ACE.ECMPods[i] - - if ECM:EntIndex() == Ent:EntIndex() then - table.remove(ACE.ECMPods, i) - --print("[ACE | INFO]- the ECM ' .. Ent:GetClass() .. ' (" .. Ent:GetModel() .. ") has been removed!") - --print('ECM registered count: ' .. table.Count( ACE.ECMPods )) - break - end + + for i, ecm in ipairs(ACE.ECMPods) do + + if IsValid(ecm) and ecm == Ent then + table.remove(ACE.ECMPods, i) + --print("ECM registered count: " .. #ACE.ECMPods) + break end end - -- Remove this Tracking Radar from list if deleted + -- Remove this Tracking Radar from list if deleted elseif Ent:GetClass() == "ace_trackingradar" then - for i = 1, table.Count(ACE.radarEntities) do - if ACE.radarEntities[i]:IsValid() and Ent:IsValid() then - local TrRadar = ACE.radarEntities[i] - - if TrRadar:EntIndex() == Ent:EntIndex() then - table.remove(ACE.radarEntities, i) - --print("[ACE | INFO]- the TrRadar ' .. Ent:GetClass() .. ' (" .. Ent:GetModel() .. ") has been removed!") - --print('Tracking radar registered count: ' .. table.Count( ACE.radarEntities )) - break - end + + for i, radar in ipairs(ACE.radarEntities) do + if IsValid(radar) and radar == Ent then + + ACE.radarIDs[Ent] = nil + + table.remove(ACE.radarEntities, i) + --print("Tracking radar registered count: " .. #ACE.radarEntities) + break end end + -- Remove this GLATGM optical Computer from list if deleted elseif Ent:GetClass() == "acf_opticalcomputer" then - -- Remove this GLATGM optical Computer from list if deleted - for i = 1, table.Count(ACE.Opticals) do - if ACE.Opticals[i]:IsValid() and Ent:IsValid() then - local Optical = ACE.Opticals[i] - - if Optical:EntIndex() == Ent:EntIndex() then - table.remove(ACE.Opticals, i) - --print("[ACE | INFO]- the Optical ' .. Ent:GetClass() .. ' (" .. Ent:GetModel() .. ") has been removed!") - --print('GLATGM optical computer registered count: ' .. table.Count( ACE.Opticals )) - break - end + + for i, optical in ipairs(ACE.Opticals) do + if IsValid(optical) and optical == Ent then + table.remove(ACE.Opticals, i) + --print("Opticals registered count: " .. #ACE.Opticals) + break end end + elseif ACE.ExplosiveEnts[Ent:GetClass()] then - for i = 1, table.Count(ACE.Explosives) do - if ACE.Explosives[i]:IsValid() and Ent:IsValid() then - local Explosive = ACE.Explosives[i] - - if Explosive:EntIndex() == Ent:EntIndex() then - table.remove(ACE.Explosives, i) - --print("[ACE | INFO]- the Explosive ' .. Ent:GetClass() .. ' (" .. Ent:GetModel() .. ") has been removed!") - --print('[ACE | INFO]- Explosive registered count: ' .. table.Count( ACE.Explosives )) - break - end + + for i, explosive in ipairs(ACE.Explosives) do + if IsValid(explosive) and explosive == Ent then + table.remove(ACE.Explosives, i) + --print("Explosive registered count: " .. #ACE.Explosives) + break end end end -- Finally, remove this Entity from the main list - --check if we are taking same ent - if MEnt:EntIndex() == Ent:EntIndex() then - table.remove(ACE.contraptionEnts, i) --if same, remove it - --print("[ACE | INFO]- the entity ' .. Ent:GetClass() .. ' (" .. Ent:GetModel() .. ") has been removed!") - --print('Total Ents registered count: ' .. #ACE.contraptionEnts) - --code has ended its work, return - + if ent == Ent then + table.remove(ACE.contraptionEnts, i) + --print("Global registered count: " .. #ACE.contraptionEnts ) return end end + elseif Ent:GetClass() == "ace_debris" then - for i = 1, #ACE.Debris do - if not IsValid(ACE.Debris[i]) then continue end + for i, debris in ipairs(ACE.Debris) do + if IsValid(debris) and debris == Ent then + table.remove(ACE.Debris, i) + --print("Debris registered count: " .. #ACE.Debris ) + end + end + elseif Ent:GetClass() == "ace_mine" then - if ACE.Debris[i]:EntIndex() == Ent:EntIndex() then - table.remove(ACE.Debris, i) --print('Removing - Count: ' .. #ACE.Debris) + local Owner = Ent.DamageOwner - return + for i, mine in ipairs(ACE.MineOwners[Owner]) do + if IsValid(mine) and mine == Ent then + table.remove(ACE.MineOwners[Owner], i) + --print("Mine registered count to player " .. Owner:Nick() .. ": " .. #ACE.MineOwners[Owner] ) + end + end + + for i, mine in ipairs(ACE.Mines) do + if IsValid(mine) and mine == Ent then + table.remove(ACE.Mines, i) + --print("Mine registered count: " .. #ACE.Mines ) end end end @@ -212,4 +216,4 @@ function ACE_refreshdata(Data) --print('Total Ents registered count: ' .. table.Count( ACE.contraptionEnts )) end -hook.Add("AdvDupe_FinishPasting", "ACE_refresh", ACE_refreshdata) \ No newline at end of file +hook.Add("AdvDupe_FinishPasting", "ACE_refresh", ACE_refreshdata) diff --git a/lua/acf/shared/ammocrates/acfcratelist.lua b/lua/acf/shared/ammocrates/acfcratelist.lua index e97c22b3..f265877d 100644 --- a/lua/acf/shared/ammocrates/acfcratelist.lua +++ b/lua/acf/shared/ammocrates/acfcratelist.lua @@ -646,7 +646,7 @@ local Shell170mm = {} Shell170mm.volume = 11630.235 AmmoTable["Shell170mm"] = Shell170mm -list.Set( "ACFEnts", "Ammo", AmmoTable ) --end ammo containers listing +ACF.Weapons.Ammo = AmmoTable --end ammo containers listing --Cube ACE_DefineModelData("Box",{ diff --git a/lua/acf/shared/armor/aluminum.lua b/lua/acf/shared/armor/aluminum.lua index 61b6381f..e9efaffa 100644 --- a/lua/acf/shared/armor/aluminum.lua +++ b/lua/acf/shared/armor/aluminum.lua @@ -84,4 +84,4 @@ if SERVER then end end -list.Set( "ACE_MaterialTypes", Material.id, Material ) +ACE.ArmorTypes[Material.id] = Material diff --git a/lua/acf/shared/armor/cast.lua b/lua/acf/shared/armor/cast.lua index eecfa376..8205da6a 100644 --- a/lua/acf/shared/armor/cast.lua +++ b/lua/acf/shared/armor/cast.lua @@ -72,4 +72,4 @@ if SERVER then end end -list.Set( "ACE_MaterialTypes", Material.id, Material ) +ACE.ArmorTypes[Material.id] = Material diff --git a/lua/acf/shared/armor/ceramic.lua b/lua/acf/shared/armor/ceramic.lua index a7e23e9c..48e12171 100644 --- a/lua/acf/shared/armor/ceramic.lua +++ b/lua/acf/shared/armor/ceramic.lua @@ -80,4 +80,4 @@ if SERVER then end end -list.Set( "ACE_MaterialTypes", Material.id, Material ) +ACE.ArmorTypes[Material.id] = Material diff --git a/lua/acf/shared/armor/era.lua b/lua/acf/shared/armor/era.lua index ffd0f60f..41b5865a 100644 --- a/lua/acf/shared/armor/era.lua +++ b/lua/acf/shared/armor/era.lua @@ -17,19 +17,19 @@ Material.resiliance = 1 Material.HEATresiliance = 1 -- Used when ERA fails to detonate. This will act like a RHA at its 25% from ERA thickness. Used by HE -Material.NCurve = 1 +Material.NCurve = 1 Material.Neffectiveness = 0.25 -Material.Nresiliance = 1 +Material.Nresiliance = 1 Material.APSensorFactor = 4 -- quotient used to determinate minimal pen for detonation for Kinetic shells Material.HEATSensorFactor = 16 -- quotient used to determinate minimal pen for detonation for chemical shells Material.spallarmor = 1 -Material.spallresist = 1 +Material.spallresist = 1 -Material.spallmult = 0 -Material.ArmorMul = 1 -Material.NormMult = 1 +Material.spallmult = 0 +Material.ArmorMul = 1 +Material.NormMult = 1 Material.Stopshock = true -- Use this value if the material is meant to stop shockwaves @@ -41,7 +41,6 @@ if SERVER then -- Ammo Types to be considered HEAT. Hardcoded Material.HEATList = { - HEAT = true, THEAT = true, HEATFS = true, @@ -50,7 +49,6 @@ if SERVER then -- Ammo Types to be considered HE. Hardcoded Material.HEList = { - HE = true, HESH = true, Frag = true @@ -183,5 +181,4 @@ if SERVER then end end -list.Set( "ACE_MaterialTypes", Material.id, Material ) -ACE.Armors = list.Get("ACE_MaterialTypes") +ACE.ArmorTypes[Material.id] = Material diff --git a/lua/acf/shared/armor/rha.lua b/lua/acf/shared/armor/rha.lua index ccbc967d..2535a19f 100644 --- a/lua/acf/shared/armor/rha.lua +++ b/lua/acf/shared/armor/rha.lua @@ -72,4 +72,4 @@ if SERVER then end end -list.Set( "ACE_MaterialTypes", Material.id, Material ) +ACE.ArmorTypes[Material.id] = Material diff --git a/lua/acf/shared/armor/rubber.lua b/lua/acf/shared/armor/rubber.lua index 95e4e4b7..624f10ba 100644 --- a/lua/acf/shared/armor/rubber.lua +++ b/lua/acf/shared/armor/rubber.lua @@ -52,7 +52,7 @@ if SERVER then local spallresist = Material.spallresist if Type == "Spall" then - specialeffectiveness = specialeffectiveness * spallresist + specialeffectiveness = Material.effectiveness * spallresist end local DmgResist = 0.01 + math.min(caliber * 10 / specialeffect, 5) * 6 @@ -190,4 +190,4 @@ if SERVER then end end -list.Set( "ACE_MaterialTypes", Material.id, Material ) +ACE.ArmorTypes[Material.id] = Material diff --git a/lua/acf/shared/armor/textolite.lua b/lua/acf/shared/armor/textolite.lua index dfc42446..9fa83199 100644 --- a/lua/acf/shared/armor/textolite.lua +++ b/lua/acf/shared/armor/textolite.lua @@ -167,4 +167,4 @@ if SERVER then end end -list.Set( "ACE_MaterialTypes", Material.id, Material ) +ACE.ArmorTypes[Material.id] = Material diff --git a/lua/acf/shared/engines/electric.lua b/lua/acf/shared/engines/electric.lua index b1f6d2b8..7c96e062 100644 --- a/lua/acf/shared/engines/electric.lua +++ b/lua/acf/shared/engines/electric.lua @@ -11,7 +11,7 @@ ACF_DefineEngine( "Electric-Small", { enginetype = "Electric", weight = 147, torque = 376, --400 - flywheelmass = 0.3, + flywheelmass = 0.07, idlerpm = 0, --40 limitrpm = 18215, iselec = true, @@ -28,7 +28,7 @@ ACF_DefineEngine( "Electric-Medium", { enginetype = "Electric", weight = 160, torque = 600, - flywheelmass = 0.35, + flywheelmass = 0.15, idlerpm = 0, limitrpm = 20000, iselec = true, @@ -46,7 +46,7 @@ ACF_DefineEngine( "Electric-Large", { enginetype = "Electric", weight = 240, torque = 800, - flywheelmass = 0.35, + flywheelmass = 0.2, idlerpm = 0, limitrpm = 20000, iselec = true, @@ -65,7 +65,7 @@ ACF_DefineEngine( "Electric-Tiny-NoBatt", { requiresfuel = true, weight = 58, --35 torque = 126, --30 - flywheelmass = 0.3, + flywheelmass = 0.05, idlerpm = 0, --40 limitrpm = 11300, iselec = true, @@ -85,7 +85,7 @@ ACF_DefineEngine( "Electric-Small-NoBatt", { requiresfuel = true, weight = 47, --25 torque = 180, --400 - flywheelmass = 0.3, + flywheelmass = 0.07, idlerpm = 0, --40 limitrpm = 18215, iselec = true, @@ -103,7 +103,7 @@ ACF_DefineEngine( "Electric-Medium-NoBatt", { requiresfuel = true, weight = 65, --800 torque = 340, - flywheelmass = 0.35, + flywheelmass = 0.15, idlerpm = 0, limitrpm = 20000, iselec = true, @@ -121,7 +121,7 @@ ACF_DefineEngine( "Electric-Large-NoBatt", { requiresfuel = true, weight = 140, --1900 torque = 580, - flywheelmass = 0.35, + flywheelmass = 0.2, idlerpm = 0, limitrpm = 20000, iselec = true, diff --git a/lua/acf/shared/fuses/d_radio.lua b/lua/acf/shared/fuses/d_radio.lua index 3646516b..39fa4e23 100644 --- a/lua/acf/shared/fuses/d_radio.lua +++ b/lua/acf/shared/fuses/d_radio.lua @@ -89,16 +89,18 @@ do if not self:IsArmed() then return false end - local MissilePos = missile:GetPos() + local MissilePos = missile.CurPos local Dist = self.Distance local trace = {} - trace.start = MissilePos - trace.endpos = MissilePos + missile.LastVel * 0.5 --small compensation for incoming impacts. - trace.filter = FilterFunction - trace.mins = Vector(-Dist, -Dist, -Dist) - trace.maxs = -trace.mins - trace.ignoreworld = true + trace.start = missile.DPos or MissilePos print(MissilePos) + trace.endpos = MissilePos --small compensation for incoming impacts. + trace.filter = FilterFunction + trace.mins = Vector(-Dist, -Dist, -Dist) + trace.maxs = -trace.mins + trace.ignoreworld = true + + missile.DPos = MissilePos local tr = util.TraceHull(trace) diff --git a/lua/acf/shared/guns/atrifle.lua b/lua/acf/shared/guns/atrifle.lua index a71c18b4..a2e1356e 100644 --- a/lua/acf/shared/guns/atrifle.lua +++ b/lua/acf/shared/guns/atrifle.lua @@ -16,7 +16,7 @@ ACF_defineGun("7.92mmATR", { --id name = "7.92mm Anti Tank Rifle", desc = "The 7.92 Anti Tank Rifle is somone's desperate attempt to fend off hordes of tracked beasts in the trenches", model = "models/machinegun/machinegun_762mm.mdl", - sound = "acf_extra/tankfx/gnomefather/7mm1.wav", + sound = "ace_weapons/multi_sound/7_62mm_multi.mp3", gunclass = "ATR", caliber = 0.792, weight = 8, @@ -34,7 +34,7 @@ ACF_defineGun("14.5mmATR", { --id name = "14.5mm Anti Tank Rifle", desc = "Commonly used by soviets as a budget way to kill tanks, still worthless.", model = "models/machinegun/machinegun_145mm.mdl", - sound = "acf_extra/tankfx/gnomefather/7mm1.wav", + sound = "ace_weapons/multi_sound/12_7mm_multi.mp3", gunclass = "ATR", caliber = 1.45, weight = 15, @@ -52,7 +52,7 @@ ACF_defineGun("20mmATR", { --id name = "20mm Anti Tank Rifle", desc = "Collosal anti tank rifle, good for putting a hole through side armor at point blank, that is if you can carry it.", model = "models/machinegun/machinegun_20mm.mdl", - sound = "acf_extra/tankfx/gnomefather/7mm1.wav", + sound = "ace_weapons/sweps/multi_sound/amr_multi.mp3", gunclass = "ATR", caliber = 2.0, weight = 23, diff --git a/lua/acf/shared/guns/grenadelauncher.lua b/lua/acf/shared/guns/grenadelauncher.lua index 2d47f44f..95608a6f 100644 --- a/lua/acf/shared/guns/grenadelauncher.lua +++ b/lua/acf/shared/guns/grenadelauncher.lua @@ -18,7 +18,7 @@ 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", - sound = "weapons/acf_gun/grenadelauncher.wav", + sound = "ace_weapons/multi_sound/30mm_hmg_multi.mp3", gunclass = "GL", caliber = 4.0, weight = 55, @@ -35,7 +35,7 @@ ACF_defineGun("20mmGL", { --id name = "20mm Grenade Launcher", desc = "The 20mm is the embodyment of wimpy weapons, although it has a large clip and can fire HE it is bloody weak using 40mm GL as placeholder bc the 20mm mini is borked", model = "models/launcher/20mmgl.mdl", - sound = "weapons/acf_gun/grenadelauncher.wav", + sound = "ace_weapons/multi_sound/12_7mm_multi.mp3", gunclass = "GL", caliber = 3.01, weight = 10, @@ -52,7 +52,7 @@ ACF_defineGun("40mmGLSingle", { --id name = "40mm Single Grenade Launcher", desc = "The 40mm grenade projecter excels at launching a small 40mm charge at nearby infantry or defending a tank from an incoming rocket.", model = "models/launcher/40mmsl.mdl", - sound = "weapons/acf_gun/grenadelauncher.wav", + sound = "ace_weapons/multi_sound/smoke_multi.mp3", gunclass = "GL", caliber = 4.0, weight = 5, diff --git a/lua/acf/shared/guns/mortar.lua b/lua/acf/shared/guns/mortar.lua index 1b57081c..3c72cac7 100644 --- a/lua/acf/shared/guns/mortar.lua +++ b/lua/acf/shared/guns/mortar.lua @@ -15,7 +15,7 @@ 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", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/40mm_multi.mp3", gunclass = "MO", caliber = 6.0, weight = 80, @@ -31,7 +31,7 @@ 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", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/40mm_multi.mp3", gunclass = "MO", caliber = 8.0, weight = 210, @@ -46,7 +46,7 @@ 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", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/40mm_multi.mp3", gunclass = "MO", caliber = 12.0, weight = 440, @@ -61,7 +61,7 @@ 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", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/40mm_multi.mp3", gunclass = "MO", caliber = 15.0, weight = 680, @@ -76,7 +76,7 @@ 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", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/40mm_multi.mp3", gunclass = "MO", caliber = 20.0, weight = 980, @@ -91,7 +91,7 @@ ACF_defineGun("50mmM", { --id name = "50mm Mortar", desc = "The 50mm is an uncommon light mortar often seen at or before the begening of ww2, it fires a light 50mm rounds that is good for splatting infantry.", model = "models/mortar/mortar_50mm.mdl", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/40mm_multi.mp3", gunclass = "MO", caliber = 5.0, weight = 40, @@ -107,7 +107,7 @@ 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", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/howitzer_multi.mp3", gunclass = "MO", caliber = 28.0, weight = 2000, @@ -122,7 +122,7 @@ ACF_defineGun("380mmM", { name = "380mm Mortar", desc = "Massive payload, with a reload time to match. Found in rare WW2 siege artillery pieces.", model = "models/mortar/mortar_300mm.mdl", - sound = "weapons/ACF_Gun/mortar_new.wav", + sound = "ace_weapons/multi_sound/howitzer_multi.mp3", gunclass = "MO", caliber = 38.0, weight = 5000, diff --git a/lua/acf/shared/guns/rotaryautocannon.lua b/lua/acf/shared/guns/rotaryautocannon.lua index 8afb2a01..4a2c0b83 100644 --- a/lua/acf/shared/guns/rotaryautocannon.lua +++ b/lua/acf/shared/guns/rotaryautocannon.lua @@ -17,7 +17,7 @@ ACF_defineGun("14.5mmRAC", { --id name = "14.5mm Rotary Autocannon", desc = "A lightweight rotary autocannon, a great support weapon for effortlessly shredding infantry and technicals alike.", model = "models/rotarycannon/kw/14_5mmrac.mdl", - sound = "weapons/acf_gun/mg_fire2.wav", + sound = "ace_weapons/multi_sound/12_7mm_multi.mp3", gunclass = "RAC", caliber = 1.45, weight = 160, @@ -33,7 +33,7 @@ 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.", model = "models/rotarycannon/kw/20mmrac.mdl", - sound = "weapons/acf_gun/mg_fire2.wav", + sound = "ace_weapons/multi_sound/20mm_hmg_multi.mp3", gunclass = "RAC", caliber = 2.0, weight = 420, @@ -49,7 +49,7 @@ 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.", model = "models/rotarycannon/kw/30mmrac.mdl", - sound = "weapons/acf_gun/mg_fire2.wav", + sound = "ace_weapons/multi_sound/30mm_hmg_multi.mp3", gunclass = "RAC", caliber = 3.0, weight = 610, diff --git a/lua/acf/shared/guns/semiauto.lua b/lua/acf/shared/guns/semiauto.lua index 2a04fdd8..0bc2717d 100644 --- a/lua/acf/shared/guns/semiauto.lua +++ b/lua/acf/shared/guns/semiauto.lua @@ -17,7 +17,7 @@ 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", - sound = "acf_extra/tankfx/gnomefather/25mm1.wav", + sound = "ace_weapons/multi_sound/20mm_multi.mp3", gunclass = "SA", caliber = 2.5, weight = 75, @@ -35,7 +35,7 @@ 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", - sound = "acf_extra/tankfx/gnomefather/25mm1.wav", + sound = "ace_weapons/multi_sound/30mm_multi.mp3", gunclass = "SA", caliber = 3.7, weight = 180, @@ -53,7 +53,7 @@ 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", - sound = "acf_extra/tankfx/gnomefather/25mm1.wav", + sound = "ace_weapons/multi_sound/40mm_multi.mp3", gunclass = "SA", caliber = 4.5, weight = 495, @@ -71,7 +71,7 @@ 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", - sound = "acf_extra/tankfx/gnomefather/25mm1.wav", + sound = "ace_weapons/multi_sound/50mm_multi.mp3", gunclass = "SA", caliber = 5.7, weight = 780, @@ -89,7 +89,7 @@ ACF_defineGun("76mmSA", { name = "76mm Semiautomatic Cannon", desc = "The 76mm semiauto is a fearsome weapon, able to put 12 76mm rounds downrange in 7 seconds.", model = "models/autocannon/semiautocannon_76mm.mdl", - sound = "acf_extra/tankfx/gnomefather/25mm1.wav", + sound = "ace_weapons/multi_sound/75mm_multi.mp3", gunclass = "SA", caliber = 7.62, weight = 1700, diff --git a/lua/acf/shared/mines/mine_apl.lua b/lua/acf/shared/mines/mine_apl.lua new file mode 100644 index 00000000..1200a3a4 --- /dev/null +++ b/lua/acf/shared/mines/mine_apl.lua @@ -0,0 +1,79 @@ +--[[ + + ACE_DefineMine( "Example-ID", { + + name = "Im a Mine", --The full name of the mine. + model = "models/cyborgmatt/capacitor_small.mdl", -- The in-game model + material = "models/props_canal/canal_bridge_railing_01c", -- The material render. Don't add one if you prefer the default model texture. + color = Color(255,255,255), -- The color. Don't add one if you prefer the original color + weight = 4, -- The weight of this mine + + heweight = 1, -- The HE filler mass + fragmass = 0.1, -- The HE frag mass + armdelay = 2, -- The time (in seconds) this mine needs to be ready to explode, since it was put on ground. + + setrange = 10, -- The trace which detects the ground. Needed when the mine is looking for ground. + + triggermins = Vector( -90, -90, -10 ), -- the trigger mins area + triggermaxs = Vector( 90, 90, 40 ), -- the same as above, but maxs + + digdepth = 7.1, -- how much (in units) from the origin center of the model will be inserted into the ground? + groundinverted = true, -- If true, the model will be put upside down when its attached to the ground. Bounding-APL model requires it + + ignoreplayers = false, -- Defines if the mine should be triggered by players or not. NPCs CAN DETONATE IT EVEN IF FALSE. + shouldjump = true, -- If true, the mine will "jump" off the ground. + jumpforce = 290, -- If the mine will jump, this will tell how much force will be put on it. + detonationdelay = 0.5, -- Same as above. How many seconds after the initial jump are required to explode + + customdetonation = function( MineEntity ) print("a custom detonation") end, -- If needed, you can override the default detonation with this. + + } ) +]] + +ACE_DefineMine( "APL", { + + name = "Conventional Anti-Personnel Landmine", + model = "models/jaanus/wiretool/wiretool_range.mdl", + material = "models/props_canal/metalwall005b", + color = Color(255,255,255), + weight = 4, + + heweight = 0.5, + fragmass = 0.1, + armdelay = 2, + + setrange = 10, + + triggermins = Vector( -60, -60, -10 ), + triggermaxs = Vector( 60, 60, 40 ), + + digdepth = 1.05, + +} ) +ACE_DefineMine( "Bounding-APL", { + + name = "Bounding Anti-Personnel Landmine", + model = "models/cyborgmatt/capacitor_small.mdl", + material = "models/props_canal/canal_bridge_railing_01c", + color = Color(255,255,255), + weight = 4, + + heweight = 1, + fragmass = 0.1, + armdelay = 2, + + setrange = 10, + + -- the trigger zone. + triggermins = Vector( -90, -90, -10 ), -- the trigger mins area, + triggermaxs = Vector( 90, 90, 40 ), -- the same as above, but maxs + + digdepth = 7.1, -- how much (in units) from the origin center of the model will be inserted into the ground? + groundinverted = true, -- If true, the model will be put upside down when its attached to the ground. Bounding-APL model requires it + + ignoreplayers = false, -- Defines if the mine should be triggered by players or not. NPCs CAN DETONATE IT EVEN IF FALSE. + shouldjump = true, -- If true, the mine will "jump" off the ground. + jumpforce = 290, -- If the mine will jump, this will tell how much force will be put on it. + detonationdelay = 0.5, -- Same as above. How many seconds after the initial jump are required to explode + +} ) diff --git a/lua/acf/shared/mines/mine_at.lua b/lua/acf/shared/mines/mine_at.lua new file mode 100644 index 00000000..a5352cd6 --- /dev/null +++ b/lua/acf/shared/mines/mine_at.lua @@ -0,0 +1,22 @@ +ACE_DefineMine( "ATL", { + + name = "Conventional Anti-Tank Landmine", + model = "models/maxofs2d/button_02.mdl", + material = "models/props_canal/metalwall005b", + color = Color(255,255,255), + weight = 8, + + heweight = 50, + fragmass = 50, + armdelay = 2, + + setrange = 10, + + -- the trigger zone. + triggermins = Vector( -30, -30, -10 ), + triggermaxs = Vector( 30, 30, 40 ), + + digdepth = 2.5, + ignoreplayers = true, + +} ) diff --git a/lua/acf/shared/missiles/missile_atgm.lua b/lua/acf/shared/missiles/missile_atgm.lua index ade3e274..28091905 100644 --- a/lua/acf/shared/missiles/missile_atgm.lua +++ b/lua/acf/shared/missiles/missile_atgm.lua @@ -103,7 +103,9 @@ ACF_defineGun("9M133 ASM", { -- id racks = { -- a whitelist for racks that this missile can load into. - ["1x Kornet"] = true + ["1x Kornet"] = true, + ["2x Kornet"] = true, + ["4x Kornet"] = true }, viewcone = 25, -- getting outside this cone will break the lock. Divided by 2. diff --git a/lua/acf/shared/missiles/pod.lua b/lua/acf/shared/missiles/pod.lua index ff8ff85f..24097f3b 100644 --- a/lua/acf/shared/missiles/pod.lua +++ b/lua/acf/shared/missiles/pod.lua @@ -11,7 +11,6 @@ ACF_DefineRackClass("POD", { hidemissile = true, protectmissile = true, - armour = 15, reloadmul = 8, } ) @@ -29,7 +28,6 @@ ACF_DefineRack("40mm7xPOD", { weight = 20, year = 1940, magsize = 7, - armour = 15, caliber = 4, reloadmul = 150, @@ -61,7 +59,6 @@ ACF_DefineRack("70mm7xPOD", { weight = 40, year = 1940, magsize = 7, - armour = 24, caliber = 7, reloadmul = 150, @@ -93,7 +90,6 @@ ACF_DefineRack("1x BGM-71E", { weight = 10, year = 1970, magsize = 1, - armour = 18, caliber = 13, whitelistonly = true, @@ -117,7 +113,6 @@ ACF_DefineRack("2x BGM-71E", { weight = 60, year = 1970, magsize = 2, - armour = 18, caliber = 13, whitelistonly = true, @@ -142,7 +137,6 @@ ACF_DefineRack("4x BGM-71E", { weight = 100, year = 1970, magsize = 4, - armour = 24, caliber = 13, whitelistonly = true, @@ -167,7 +161,6 @@ ACF_DefineRack("380mmRW61", { weight = 600, year = 1945, magsize = 1, - armour = 24, caliber = 38, hidemissile = false, @@ -192,7 +185,6 @@ ACF_DefineRack("3xUARRK", { gunclass = "POD", weight = 150, year = 1941, - armour = 30, magsize = 3, protectmissile = true, @@ -215,7 +207,6 @@ ACF_DefineRack("6xUARRK", { gunclass = "POD", weight = 600, year = 1980, - armour = 45, magsize = 6, protectmissile = true, @@ -245,7 +236,6 @@ ACF_DefineRack("1x FIM-92", { weight = 10, year = 1984, magsize = 1, - armour = 12, caliber = 11, protectmissile = true, hidemissile = false, @@ -265,7 +255,6 @@ ACF_DefineRack("2x FIM-92", { weight = 30, year = 1984, magsize = 2, - armour = 16, caliber = 11, rofmod = 3, @@ -288,7 +277,6 @@ ACF_DefineRack("4x FIM-92", { weight = 30, year = 1984, magsize = 4, - armour = 20, caliber = 11, protectmissile = true, @@ -313,7 +301,6 @@ ACF_DefineRack("1x Strela-1", { weight = 10, year = 1968, magsize = 1, - armour = 50, caliber = 12, protectmissile = true, @@ -334,7 +321,6 @@ ACF_DefineRack("2x Strela-1", { weight = 30, year = 1968, magsize = 2, - armour = 80, caliber = 12, protectmissile = true, @@ -357,7 +343,6 @@ ACF_DefineRack("4x Strela-1", { weight = 50, year = 1968, magsize = 4, - armour = 100, caliber = 12, protectmissile = true, @@ -382,7 +367,6 @@ ACF_DefineRack("1x Ataka", { weight = 10, year = 1968, magsize = 1, - armour = 50, caliber = 13, protectmissile = true, @@ -404,7 +388,6 @@ ACF_DefineRack("1x SPG9", { weight = 90, year = 1968, magsize = 1, - armour = 30, caliber = 7.3, spread = 0.1, @@ -418,28 +401,74 @@ ACF_DefineRack("1x SPG9", { } } ) ---Kornet tube +-- 1 Kornet tube ACF_DefineRack("1x Kornet", { - name = "Kornet Launch Tube", - desc = "Launch tube for Kornet antitank missile.", - model = "models/kali/weapons/kornet/parts/9m133 kornet tube.mdl", - gunclass = "POD", - weight = 30, - year = 1994, - magsize = 1, - armour = 20, - caliber = 15.2, + name = "Kornet Launch Tube", + desc = "Launch tube for Kornet antitank missile.", + model = "models/kali/weapons/kornet/parts/9m133 kornet tube.mdl", + gunclass = "POD", + weight = 30, + year = 1994, + magsize = 1, + caliber = 15.2, + + protectmissile = true, + hidemissile = true, + whitelistonly = true, - protectmissile = true, - hidemissile = true, - whitelistonly = true, + mountpoints = + { + missile1 = { pos = Vector(0,0,0), scaledir = Vector(0,0,0) } + } +} ) + +-- 2 Kornet tube +ACF_DefineRack("2x Kornet", { + name = "Kornet Launch Tube", + desc = "A double Launch tube for 2 Kornet missiles.", + model = "models/missiles/kornetrack2.mdl", + gunclass = "POD", + weight = 60, + year = 1994, + magsize = 2, + caliber = 15.2, + + protectmissile = true, + hidemissile = true, + whitelistonly = true, mountpoints = { - ["missile1"] = { ["pos"] = Vector(0,0,0), ["offset"] = Vector(0,0,0), ["scaledir"] = Vector(0,0,0)} + missile1 = { pos = Vector(2,-7.3,-1), scaledir = Vector(0,0,0) }, + missile2 = { pos = Vector(2,7.3,-1), scaledir = Vector(0,0,0) }, } } ) +-- 4 Kornet tube +ACF_DefineRack("4x Kornet", { + name = "Kornet Launch Tube", + desc = "A Quad Launch tube for 4 Kornet missiles.", + model = "models/missiles/kornetrack4.mdl", + gunclass = "POD", + weight = 120, + year = 1994, + magsize = 4, + caliber = 15.2, + + protectmissile = true, + hidemissile = true, + whitelistonly = true, + + mountpoints = + { + missile1 = { pos = Vector(-1,-7.3,4.5), scaledir = Vector(0,0,0) }, + missile2 = { pos = Vector(-1,7.3,4.5), scaledir = Vector(0,0,0) }, + missile3 = { pos = Vector(-1,-7.3,-6.5), scaledir = Vector(0,0,0) }, + missile4 = { pos = Vector(-1,7.3,-6.5), scaledir = Vector(0,0,0) }, + } +} ) + + --Zuni pod ACF_DefineRack("127mm4xPOD", { name = "5.0 Inch Zuni Pod", @@ -449,7 +478,6 @@ ACF_DefineRack("127mm4xPOD", { weight = 100, year = 1957, magsize = 4, - armour = 40, caliber = 12.7, protectmissile = true, @@ -474,7 +502,6 @@ ACF_DefineRack("1x 9m311", { weight = 10, year = 1970, magsize = 1, - armour = 18, caliber = 12, whitelistonly = true, @@ -496,7 +523,6 @@ ACF_DefineRack("1x Javelin", { weight = 6.4, year = 1989, magsize = 1, - armour = 20, caliber = 12.7, protectmissile = true, diff --git a/lua/acf/shared/missiles/rack.lua b/lua/acf/shared/missiles/rack.lua index 2e369aa2..f3dea605 100644 --- a/lua/acf/shared/missiles/rack.lua +++ b/lua/acf/shared/missiles/rack.lua @@ -1,12 +1,11 @@ --define the class ACF_DefineRackClass("RK", { - spread = 1, - name = "Munitions Rack", - desc = "A lightweight rack for rockets and bombs which is vulnerable to shots and explosions.", - muzzleflash = "40mm_muzzleflash_noscale", - rofmod = 1, - - reloadmul = 8, + spread = 1, + name = "Munitions Rack", + desc = "A lightweight rack for rockets and bombs which is vulnerable to shots and explosions.", + muzzleflash = "40mm_muzzleflash_noscale", + rofmod = 1, + reloadmul = 8, } ) @@ -22,7 +21,7 @@ ACF_DefineRack("1xRK", { rofmod = 2, year = 1915, magsize = 1, - armour = 20, + mountpoints = { @@ -40,7 +39,6 @@ ACF_DefineRack("1xRK_small", { rofmod = 2, year = 1915, magsize = 1, - armour = 20, mountpoints = { @@ -58,7 +56,6 @@ ACF_DefineRack("2xRK", { weight = 75, year = 1915, magsize = 2, - armour = 20, mountpoints = { @@ -74,7 +71,7 @@ ACF_DefineRack("3xRK", { gunclass = "RK", weight = 100, year = 1936, - armour = 20, + magsize = 3, mountpoints = @@ -92,7 +89,6 @@ ACF_DefineRack("4xRK", { gunclass = "RK", weight = 125, year = 1936, - armour = 20, magsize = 4, mountpoints = @@ -112,7 +108,6 @@ ACF_DefineRack("2x AGM-114", { weight = 50, year = 1984, magsize = 2, - armour = 20, caliber = 16, mountpoints = @@ -130,7 +125,6 @@ ACF_DefineRack("4x AGM-114", { weight = 100, year = 1984, magsize = 4, - armour = 20, caliber = 16, mountpoints = @@ -152,7 +146,6 @@ ACF_DefineRack("1xAT3RK", { rofmod = 1.4, year = 1969, magsize = 1, - armour = 15, mountpoints = { @@ -169,7 +162,6 @@ ACF_DefineRack("1xAT3RKS", { rofmod = 1.0, year = 1972, magsize = 1, - armour = 15, mountpoints = { diff --git a/lua/acf/shared/rounds/roundap.lua b/lua/acf/shared/rounds/roundap.lua index 634c054a..1fc88536 100644 --- a/lua/acf/shared/rounds/roundap.lua +++ b/lua/acf/shared/rounds/roundap.lua @@ -204,7 +204,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id -- AmmoSelect GUI - PlayerData.Type = Round.Type -- Hardcoded, match ACFRoundTypes table index + PlayerData.Type = Round.Type -- Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength -- PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength -- ProjLength slider PlayerData.Tracer = acfmenupanel.AmmoData.Tracer @@ -228,8 +228,6 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", Round.Type , Round ) -list.Set( "ACFRoundTypes", Round.Type, Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, Round.Type ) --Index must equal the ID entry in the table above, Data must equal the index of the table above -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundapbc.lua b/lua/acf/shared/rounds/roundapbc.lua index 9b072a4a..6c34aa45 100644 --- a/lua/acf/shared/rounds/roundapbc.lua +++ b/lua/acf/shared/rounds/roundapbc.lua @@ -9,6 +9,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" -- Shell flight model Round.desc = ACFTranslation.ShellAPBC[2] Round.netid = 18 -- Unique ammotype ID for network transmission +Round.Type = "APBC" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -200,7 +202,7 @@ function Round.guiupdate( Panel, _ ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "APBC" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "APBC" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Tracer = acfmenupanel.AmmoData.Tracer @@ -225,5 +227,5 @@ function Round.guiupdate( Panel, _ ) end list.Set( "APRoundTypes", "APBC", Round ) -list.Set( "ACFRoundTypes", "APBC", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "APBC" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --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/roundapc.lua b/lua/acf/shared/rounds/roundapc.lua index 5c3a676e..1f90d515 100644 --- a/lua/acf/shared/rounds/roundapc.lua +++ b/lua/acf/shared/rounds/roundapc.lua @@ -9,6 +9,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" -- Shell flight model Round.desc = ACFTranslation.ShellAPC[2] Round.netid = 17 -- Unique ammotype ID for network transmission +Round.Type = "APC" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -97,7 +99,7 @@ end function Round.normalize( _, Bullet, HitPos, HitNormal, Target) local Mat = Target.ACF.Material or "RHA" - local NormieMult = ACE.Armors[ Mat ].NormMult or 1 + local NormieMult = ACE.ArmorTypes[ Mat ].NormMult or 1 Bullet.Normalize = true Bullet.Pos = HitPos @@ -228,7 +230,7 @@ function Round.guiupdate( Panel, _ ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "APC" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "APC" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Tracer = acfmenupanel.AmmoData.Tracer @@ -252,5 +254,5 @@ function Round.guiupdate( Panel, _ ) end list.Set( "APRoundTypes", "APC", Round ) -list.Set( "ACFRoundTypes", "APC", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "APC" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundapcbc.lua b/lua/acf/shared/rounds/roundapcbc.lua index 82766ff2..63084bfc 100644 --- a/lua/acf/shared/rounds/roundapcbc.lua +++ b/lua/acf/shared/rounds/roundapcbc.lua @@ -9,6 +9,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" -- Shell flight model Round.desc = ACFTranslation.ShellAPCBC[2] Round.netid = 19 -- Unique ammotype ID for network transmission +Round.Type = "APCBC" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -100,7 +102,7 @@ end function Round.normalize( _, Bullet, HitPos, HitNormal, Target) local Mat = Target.ACF.Material or "RHA" - local NormieMult = ACE.Armors[ Mat ].NormMult or 1 + local NormieMult = ACE.ArmorTypes[ Mat ].NormMult or 1 Bullet.Normalize = true Bullet.Pos = HitPos @@ -231,7 +233,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "APCBC" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "APCBC" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Tracer = acfmenupanel.AmmoData.Tracer @@ -255,5 +257,5 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", "APCBC", Round ) -list.Set( "ACFRoundTypes", "APCBC", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "APCBC" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundapds.lua b/lua/acf/shared/rounds/roundapds.lua index 5f99e863..712ca466 100644 --- a/lua/acf/shared/rounds/roundapds.lua +++ b/lua/acf/shared/rounds/roundapds.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/dart_100mm.mdl" --Shell flight model Round.desc = ACFTranslation.ShellAPDS[2] Round.netid = 9 --Unique ammotype ID for network transmission +Round.Type = "APDS" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -276,7 +278,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "APDS" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "APDS" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.SCalMult @@ -303,5 +305,5 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", "APDS", Round ) -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 +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundapfsds.lua b/lua/acf/shared/rounds/roundapfsds.lua index cdedd5d4..0417ce7c 100644 --- a/lua/acf/shared/rounds/roundapfsds.lua +++ b/lua/acf/shared/rounds/roundapfsds.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/dart_100mm.mdl" --Shell flight model Round.desc = ACFTranslation.ShellAPFSDS[2] Round.netid = 16 --Unique ammotype ID for network transmission +Round.Type = "APFSDS" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -222,7 +224,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "APFSDS" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "APFSDS" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.SCalMult @@ -249,8 +251,5 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", "APFSDS", Round ) -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 - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundaphe.lua b/lua/acf/shared/rounds/roundaphe.lua index deb887de..dfefa429 100644 --- a/lua/acf/shared/rounds/roundaphe.lua +++ b/lua/acf/shared/rounds/roundaphe.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellAPHE[2] Round.netid = 5 --Unique ammotype ID for network transmission +Round.Type = "APHE" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -238,7 +240,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "APHE" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "APHE" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -271,8 +273,5 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", "APHE", Round ) -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 - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundaphecbc.lua b/lua/acf/shared/rounds/roundaphecbc.lua index 3177593b..7255113e 100644 --- a/lua/acf/shared/rounds/roundaphecbc.lua +++ b/lua/acf/shared/rounds/roundaphecbc.lua @@ -9,6 +9,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" -- Shell flight model Round.desc = ACFTranslation.ShellAPHECBC[2] Round.netid = 21 -- Unique ammotype ID for network transmission +Round.Type = "APHECBC" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -125,7 +127,7 @@ end function Round.normalize( _, Bullet, HitPos, HitNormal, Target) local Mat = Target.ACF.Material or "RHA" - local NormieMult = ACE.Armors[ Mat ].NormMult or 1 + local NormieMult = ACE.ArmorTypes[ Mat ].NormMult or 1 Bullet.Normalize = true Bullet.Pos = HitPos @@ -268,7 +270,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "APHECBC" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "APHECBC" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -297,8 +299,5 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", "APHECBC", Round ) -list.Set( "ACFRoundTypes", "APHECBC", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "APHECBC" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundfl.lua b/lua/acf/shared/rounds/roundfl.lua index e63952e6..a185801a 100644 --- a/lua/acf/shared/rounds/roundfl.lua +++ b/lua/acf/shared/rounds/roundfl.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/dart_100mm.mdl" -- Shell flight model Round.desc = ACFTranslation.ShellFL[2] Round.netid = 8 -- Unique ammotype ID for network transmission +Round.Type = "FL" + function Round.create( Gun, BulletData ) --setup flechettes @@ -169,10 +171,10 @@ function Round.cratetxt( BulletData ) local DData = Round.getDisplayData(BulletData) local inaccuracy = 0 - local Gun = list.Get("ACFEnts").Guns[BulletData.Id] + local Gun = ACF.Weapons.Guns[BulletData.Id] if Gun then - local Classes = list.Get("ACFClasses") + local Classes = ACF.Classes inaccuracy = (Classes.GunClass[Gun.gunclass] or {spread = 0}).spread end @@ -299,7 +301,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData["Id"] = acfmenupanel.AmmoData["Data"]["id"] --AmmoSelect GUI - PlayerData["Type"] = "FL" --Hardcoded, match ACFRoundTypes table index + PlayerData["Type"] = "FL" --Hardcoded, match as Round.Type instead PlayerData["PropLength"] = acfmenupanel.AmmoData["PropLength"] --PropLength slider PlayerData["ProjLength"] = acfmenupanel.AmmoData["ProjLength"] --ProjLength slider PlayerData["Data5"] = acfmenupanel.AmmoData["Flechettes"] --Flechette count slider @@ -329,5 +331,5 @@ function Round.guiupdate( Panel ) end list.Set( "SPECSRoundTypes", "FL", Round ) -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 +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundflare.lua b/lua/acf/shared/rounds/roundflare.lua index a80a5cb7..b1d27a4e 100644 --- a/lua/acf/shared/rounds/roundflare.lua +++ b/lua/acf/shared/rounds/roundflare.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellFLR[2] Round.netid = 8 --Unique ammotype ID for network transmission +Round.Type = "FLR" + function Round.create( Gun, BulletData ) local ent = ents.Create( "ace_flare" ) @@ -207,7 +209,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "FLR" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "FLR" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -241,8 +243,5 @@ function Round.guiupdate( Panel ) end list.Set( "SPECSRoundTypes", "FLR", Round ) -list.Set( "ACFRoundTypes", "FLR", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "FLR" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundglgm.lua b/lua/acf/shared/rounds/roundglgm.lua index 50cadcfc..441680e7 100644 --- a/lua/acf/shared/rounds/roundglgm.lua +++ b/lua/acf/shared/rounds/roundglgm.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellGLGM[2] Round.netid = 9 --Unique ammotype ID for network transmission +Round.Type = "GLATGM" + function Round.create( Gun, BulletData ) if Gun:GetClass() == "acf_ammo" then ACF_CreateBullet( BulletData ) @@ -358,7 +360,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "GLATGM" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "GLATGM" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -413,8 +415,5 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "GLATGM", Round ) -list.Set( "ACFRoundTypes", "GLATGM", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "GLATGM" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundhe.lua b/lua/acf/shared/rounds/roundhe.lua index a9b03015..5a6b8a22 100644 --- a/lua/acf/shared/rounds/roundhe.lua +++ b/lua/acf/shared/rounds/roundhe.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellHE[2] Round.netid = 2 --Unique ammotype ID for network transmission +Round.Type = "HE" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -215,7 +217,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "HE" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "HE" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -255,8 +257,5 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "HE", Round ) --Set the round on chemical folder -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 - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundheat.lua b/lua/acf/shared/rounds/roundheat.lua index 6eaab593..41576937 100644 --- a/lua/acf/shared/rounds/roundheat.lua +++ b/lua/acf/shared/rounds/roundheat.lua @@ -12,6 +12,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellHEAT[2] Round.netid = 4 --Unique ammotype ID for network transmission +Round.Type = "HEAT" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -376,7 +378,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "HEAT" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "HEAT" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -432,8 +434,5 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "HEAT", Round ) -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 - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundheatfs.lua b/lua/acf/shared/rounds/roundheatfs.lua index 783a353d..b12c0dc1 100644 --- a/lua/acf/shared/rounds/roundheatfs.lua +++ b/lua/acf/shared/rounds/roundheatfs.lua @@ -12,6 +12,8 @@ Round.model = "models/munitions/round_100mm_mortar_shot.mdl" --Shell flight mode Round.desc = ACFTranslation.ShellHEATFS[2] Round.netid = 18 --Unique ammotype ID for network transmission +Round.Type = "HEATFS" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -378,7 +380,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "HEATFS" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "HEATFS" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -432,8 +434,5 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "HEATFS", Round ) -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 - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundhefs.lua b/lua/acf/shared/rounds/roundhefs.lua index 877894b0..7272c369 100644 --- a/lua/acf/shared/rounds/roundhefs.lua +++ b/lua/acf/shared/rounds/roundhefs.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_mortar_shot.mdl" --Shell flight mode Round.desc = ACFTranslation.ShellHEFS[2] Round.netid = 19 --Unique ammotype ID for network transmission +Round.Type = "HEFS" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -220,7 +222,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "HEFS" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "HEFS" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -260,8 +262,5 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "HEFS", Round ) --Set the round on chemical folder -list.Set( "ACFRoundTypes", "HEFS", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "HEFS" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundhesh.lua b/lua/acf/shared/rounds/roundhesh.lua index b5ee4547..c52368e3 100644 --- a/lua/acf/shared/rounds/roundhesh.lua +++ b/lua/acf/shared/rounds/roundhesh.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellHESH[2] Round.netid = 12 --Unique ammotype ID for network transmission +Round.Type = "HESH" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -224,7 +226,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "HESH" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "HESH" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -264,8 +266,5 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "HESH", Round ) --Set the round on chemical folder -list.Set( "ACFRoundTypes", "HESH", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "HESH" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundhp.lua b/lua/acf/shared/rounds/roundhp.lua index f8fe17f6..3d1f34ec 100644 --- a/lua/acf/shared/rounds/roundhp.lua +++ b/lua/acf/shared/rounds/roundhp.lua @@ -1,8 +1,8 @@ AddCSLuaFile() -local RoundTypes = list.Get( "ACFRoundTypes" ) -local Round = RoundTypes.AP -- inherit from AP +local RoundTypes = ACF.RoundTypes +local Round = table.Copy(RoundTypes.AP) -- inherit from AP ACF.AmmoBlacklist.HP = ACF.AmmoBlacklist.AP @@ -12,6 +12,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.HP[2] Round.netid = 3 --Unique ammotype ID for network transmission +Round.Type = "HP" + -- Function to convert the player's slider data into the complete round data function Round.convert( _, PlayerData ) @@ -132,7 +134,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "HP" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "HP" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.CavVol @@ -158,8 +160,5 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", "HP", Round ) -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 - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundhvap.lua b/lua/acf/shared/rounds/roundhvap.lua index 3e721981..8d16752d 100644 --- a/lua/acf/shared/rounds/roundhvap.lua +++ b/lua/acf/shared/rounds/roundhvap.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellAPCR[2] Round.netid = 11 --Unique ammotype ID for network transmission +Round.Type = "HVAP" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -237,7 +239,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "HVAP" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "HVAP" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.SCalMult @@ -264,8 +266,5 @@ function Round.guiupdate( Panel ) end list.Set( "APRoundTypes", "HVAP", Round ) -list.Set( "ACFRoundTypes", "HVAP", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "HVAP" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundrefill.lua b/lua/acf/shared/rounds/roundrefill.lua index 0041b27d..4ad17abb 100644 --- a/lua/acf/shared/rounds/roundrefill.lua +++ b/lua/acf/shared/rounds/roundrefill.lua @@ -8,6 +8,8 @@ Round.name = "[Supply] - " .. ACFTranslation.ShellRef[1] --Human readable name Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellRef[2] +Round.Type = "Refill" + -- Function to convert the player's slider data into the complete round data function Round.convert() @@ -72,4 +74,4 @@ function Round.guiupdate() end list.Set( "SPECSRoundTypes", "Refill", Round ) -list.Set( "ACFRoundTypes", "Refill", Round ) --Set the round properties +ACF.RoundTypes[Round.Type] = Round --Set the round properties \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundsmoke.lua b/lua/acf/shared/rounds/roundsmoke.lua index 72f51285..9be548e6 100644 --- a/lua/acf/shared/rounds/roundsmoke.lua +++ b/lua/acf/shared/rounds/roundsmoke.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.ShellSm[2] Round.netid = 6 --Unique ammotype ID for network transmission +Round.Type = "SM" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -278,7 +280,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "SM" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "SM" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -317,8 +319,5 @@ function Round.guiupdate( Panel ) end list.Set( "SPECSRoundTypes", "SM", Round ) -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 - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundtheat.lua b/lua/acf/shared/rounds/roundtheat.lua index e54055e0..377b042b 100644 --- a/lua/acf/shared/rounds/roundtheat.lua +++ b/lua/acf/shared/rounds/roundtheat.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_shot.mdl" --Shell flight model Round.desc = ACFTranslation.THEAT[2] Round.netid = 15 --Unique ammotype ID for network transmission +Round.Type = "THEAT" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -462,7 +464,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "THEAT" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "THEAT" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -507,8 +509,5 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "THEAT", Round ) -list.Set( "ACFRoundTypes", "THEAT", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "THEAT" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above - -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/rounds/roundtheatfs.lua b/lua/acf/shared/rounds/roundtheatfs.lua index 7050248a..5e2b2276 100644 --- a/lua/acf/shared/rounds/roundtheatfs.lua +++ b/lua/acf/shared/rounds/roundtheatfs.lua @@ -11,6 +11,8 @@ Round.model = "models/munitions/round_100mm_mortar_shot.mdl" --Shell flight mode Round.desc = ACFTranslation.THEATFS[2] Round.netid = 19 --Unique ammotype ID for network transmission +Round.Type = "THEATFS" + function Round.create( _, BulletData ) ACF_CreateBullet( BulletData ) @@ -409,7 +411,7 @@ function Round.guiupdate( Panel ) local PlayerData = {} PlayerData.Id = acfmenupanel.AmmoData.Data.id --AmmoSelect GUI - PlayerData.Type = "THEATFS" --Hardcoded, match ACFRoundTypes table index + PlayerData.Type = "THEATFS" --Hardcoded, match as Round.Type instead PlayerData.PropLength = acfmenupanel.AmmoData.PropLength --PropLength slider PlayerData.ProjLength = acfmenupanel.AmmoData.ProjLength --ProjLength slider PlayerData.Data5 = acfmenupanel.AmmoData.FillerVol @@ -454,8 +456,6 @@ function Round.guiupdate( Panel ) end list.Set("HERoundTypes", "THEATFS", Round ) -list.Set( "ACFRoundTypes", "THEATFS", Round ) --Set the round properties -list.Set( "ACFIdRounds", Round.netid, "THEATFS" ) --Index must equal the ID entry in the table above, Data must equal the index of the table above -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") +ACF.RoundTypes[Round.Type] = Round --Set the round properties +ACF.IdRounds[Round.netid] = Round.Type --Index must equal the ID entry in the table above, Data must equal the index of the table above \ No newline at end of file diff --git a/lua/acf/shared/sh_ace_concommands.lua b/lua/acf/shared/sh_ace_concommands.lua index 550a0f9c..3f4841f8 100644 --- a/lua/acf/shared/sh_ace_concommands.lua +++ b/lua/acf/shared/sh_ace_concommands.lua @@ -16,6 +16,34 @@ if SERVER then end) + concommand.Add( "acf_mines_clear", function(ply) + + if IsValid(ply) and not ply:IsAdmin() then return end + + if next(ACE.Mines) then + for _, mine in ipairs(ACE.Mines) do + if IsValid(mine) then + mine:Remove() + end + end + end + + end) + + concommand.Add( "acf_mines_explode_all", function(ply) + + if IsValid(ply) and not ply:IsSuperAdmin() then return end + + if next(ACE.Mines) then + for _, mine in ipairs(ACE.Mines) do + if IsValid(mine) then + mine:Detonate() + end + end + end + + end) + do local function msgToCaller( ply, hud, msg ) diff --git a/lua/acf/shared/sh_ace_functions.lua b/lua/acf/shared/sh_ace_functions.lua index fc5669ee..0f4b6748 100644 --- a/lua/acf/shared/sh_ace_functions.lua +++ b/lua/acf/shared/sh_ace_functions.lua @@ -82,6 +82,51 @@ function ACF_CalcEnginePerformanceData(curve, maxTq, idle, redline) } end +-- A cheap way to check if the distance between 2 points is within a target distance. +function ACE_InDist( Pos1, Pos2, Distance ) + return (Pos2 - Pos1):LengthSqr() < Distance ^ 2 +end + + -- 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 + +function ACE_GetMaterialName( Mat ) + --concrete + local GroundMat = "Concrete" + + -- Dirt + if Mat == 68 or Mat == 79 or Mat == 85 then + GroundMat = "Dirt" + -- Sand + elseif Mat == 78 then + GroundMat = "Sand" + -- Glass + elseif Mat == 89 then + GroundMat = "Glass" + elseif Mat == 77 or Mat == 86 or Mat == 80 then + GroundMat = "Metal" + end + + return GroundMat +end + -- changes here will be automatically reflected in the armor properties tool function ACF_CalcArmor( Area, Ductility, Mass ) @@ -395,7 +440,7 @@ do end end - local MatData = ACE.Armors[Mat] + local MatData = ACE.ArmorTypes[Mat] return MatData end @@ -404,7 +449,7 @@ end --TODO: Use a universal function function ACE_CheckMaterial( MatId ) - local matdata = ACE.Armors[ MatId ] + local matdata = ACE.ArmorTypes[ MatId ] if not matdata then return false end @@ -475,6 +520,51 @@ function ACE_CheckFuelTank( fueltankid ) return true end +if SERVER then + function ACE_SendMsg(ply, ...) + net.Start("ACE_SendMessage") + net.WriteBool(false) + net.WriteTable({...}) + net.Send(ply) + end + + function ACE_SendNotification(ply, hint, duration) + net.Start("ACE_SendMessage") + net.WriteBool(true) + net.WriteString(hint) + net.WriteUInt(duration or 7, 8) + net.Send(ply) + end + + function ACE_BroadcastMsg(...) + net.Start("ACE_SendMessage") + net.WriteBool(false) + net.WriteTable({...}) + net.Broadcast() + end +else + net.Receive("ACE_SendMessage", function() + local isHint = net.ReadBool() + + if isHint then + local hint = net.ReadString() + local duration = net.ReadUInt(8) + + notification.AddLegacy(hint, NOTIFY_GENERIC, duration) + else + local msg = net.ReadTable() + + for k, v in pairs(msg) do + if type(v) == "table" and #v == 4 then -- For some reason, color objects are sometimes converted to tables during networking? + msg[k] = Color(v[1], v[2], v[3], v[4]) + end + end + + chat.AddText(unpack(msg)) + end + end) +end + --[[ IDK if this will take some usage function ACE_Msg( type, txt ) diff --git a/lua/acf/shared/sh_ace_loader.lua b/lua/acf/shared/sh_ace_loader.lua index a085f685..fce47535 100644 --- a/lua/acf/shared/sh_ace_loader.lua +++ b/lua/acf/shared/sh_ace_loader.lua @@ -21,6 +21,7 @@ local MobilityTable = {} local GSoundData = {} local ModelData = {} +local MineData = {} -- setup base classes local gun_base = { @@ -210,6 +211,11 @@ function ACE_DefineModelData( id, data ) ModelData[data.Model] = data -- I will allow both model or fast name as id. end +function ACE_DefineMine(id, data) + data.id = id + MineData[id] = data +end + -- Getters for guidance names, for use in missile definitions. local function GetAllInTableExcept(tbl, list) @@ -262,6 +268,7 @@ do "armor", "guns", "missiles", + "mines", "radars", "ammocrates", "engines", @@ -284,33 +291,22 @@ do end -ACF.RoundTypes = list.Get("ACFRoundTypes") -ACF.IdRounds = list.Get("ACFIdRounds") --Lookup tables so i can get rounds classes from clientside with just an integer - -- now that the tables are populated, throw them in the acf ents list -list.Set( "ACFClasses" , "GunClass" , GunClasses ) -list.Set( "ACFClasses" , "Rack" , RackClasses ) -list.Set( "ACFClasses" , "Radar" , RadarClasses ) - -list.Set( "ACFEnts" , "Guns" , GunTable ) -list.Set( "ACFEnts" , "Racks" , RackTable ) -list.Set( "ACFEnts" , "Engines" , EngineTable ) -list.Set( "ACFEnts" , "Gearboxes" , GearboxTable ) -list.Set( "ACFEnts" , "FuelTanks" , FuelTankTable ) -list.Set( "ACFEnts" , "FuelTanksSize", FuelTankSizeTable ) -list.Set( "ACFEnts" , "Radars" , Radars ) - -list.Set( "ACESounds" , "GunFire" , GSoundData ) - ---Small remainder of Mobility table. Still being used in stuff like starfall/e2. This can change - -list.Set( "ACFEnts" , "Mobility" , MobilityTable ) - -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 - -ACE.Armors = list.Get("ACE_MaterialTypes") -ACE.GSounds = list.Get("ACESounds") -ACE.ModelData = ModelData +ACF.Classes.GunClass = GunClasses +ACF.Classes.Rack = RackClasses +ACF.Classes.Radar = RadarClasses + +ACF.Weapons.Guns = GunTable +ACF.Weapons.Racks = RackTable +ACF.Weapons.Engines = EngineTable +ACF.Weapons.Gearboxes = GearboxTable +ACF.Weapons.FuelTanks = FuelTankTable +ACF.Weapons.FuelTanksSize = FuelTankSizeTable +ACF.Weapons.Radars = Radars + +--Small reminder of Mobility table. Still being used in stuff like starfall/e2. This can change +ACF.Weapons.Mobility = MobilityTable + +ACE.GSounds.GunFire = GSoundData +ACE.ModelData = ModelData +ACE.MineData = MineData \ No newline at end of file diff --git a/lua/acf/shared/sh_acfm_getters.lua b/lua/acf/shared/sh_acfm_getters.lua index cefa6ba2..61a43cef 100644 --- a/lua/acf/shared/sh_acfm_getters.lua +++ b/lua/acf/shared/sh_acfm_getters.lua @@ -24,7 +24,7 @@ function ACF_GetGunValue(bdata, val) if ret ~= nil then return ret else - local classes = list.Get("ACFClasses").GunClass + local classes = ACF.Classes.GunClass class = classes[class.gunclass] if class then @@ -122,7 +122,7 @@ function ACF_CanLinkRack(rackId, ammoId, bdata, rack) return false, calMsg end - local Classes = list.Get("ACFClasses").GunClass + local Classes = ACF.Classes.GunClass if "missile" ~= Classes[gun.gunclass].type then return false, "Racks cannot be linked to ammo crates of type '" .. tostring(ammoId) .. "'!" end diff --git a/lua/acf/shared/sh_acfm_roundinject.lua b/lua/acf/shared/sh_acfm_roundinject.lua index bd8e4858..31d36df4 100644 --- a/lua/acf/shared/sh_acfm_roundinject.lua +++ b/lua/acf/shared/sh_acfm_roundinject.lua @@ -9,7 +9,7 @@ include("acf/shared/sh_acfm_getters.lua") local function checkIfDataIsMissile(data) - local guns = list.Get("ACFEnts").Guns + local guns = ACF.Weapons.Guns local class = guns[data.Id] if not (class and class.gunclass) then @@ -19,7 +19,7 @@ local function checkIfDataIsMissile(data) return end - local classes = list.Get("ACFClasses").GunClass + local classes = ACF.Classes.GunClass class = classes[class.gunclass] return class.type and class.type == "missile" @@ -31,7 +31,7 @@ end function ACFM_ModifyRoundDisplayFuncs() - local roundTypes = list.GetForEdit("ACFRoundTypes") + local roundTypes = ACF.RoundTypes if not ACFM_RoundDisplayFuncs then @@ -98,7 +98,7 @@ end function ACFM_ModifyCrateTextFuncs() - local roundTypes = list.GetForEdit("ACFRoundTypes") + local roundTypes = ACF.RoundTypes if not ACFM_CrateTextFuncs then diff --git a/lua/acf/shared/sounds/gunfire.lua b/lua/acf/shared/sounds/gunfire.lua index 05f2fa66..7eef56c4 100644 --- a/lua/acf/shared/sounds/gunfire.lua +++ b/lua/acf/shared/sounds/gunfire.lua @@ -620,7 +620,7 @@ ACE_DefineGunFireSound( "ace_weapons/multi_sound/howitzer_multi.wav", } } ) - +--[[ --Generic Mortar gunfire. Ik its empty, the structure is here just to avoid recreate it in the future. ACE_DefineGunFireSound( "weapons/ACF_Gun/mortar_new.wav", { @@ -648,7 +648,7 @@ ACE_DefineGunFireSound( "weapons/ACF_Gun/mortar_new.wav", } } ) - +]] --Generic AT Rifle gunfire ACE_DefineGunFireSound( "acf_extra/tankfx/gnomefather/7mm1.wav", { @@ -717,6 +717,7 @@ ACE_DefineGunFireSound( "weapons/acf_gun/mg_fire2.wav", } ) ]] +--[[ --Generic GL gunfire ACE_DefineGunFireSound( "weapons/acf_gun/grenadelauncher.wav", { @@ -800,7 +801,7 @@ ACE_DefineGunFireSound( "acf_extra/tankfx/flare_launch.wav", } } ) - +]]-- --[[ --Test sound definition. Meant to see if the core works as intended. ACE_DefineGunFireSound( "physics/metal/bts5_panels_impact_lg_01.wav", diff --git a/lua/acf/shared/sounds/sweps.lua b/lua/acf/shared/sounds/sweps.lua index 44a29b6f..92a371d6 100644 --- a/lua/acf/shared/sounds/sweps.lua +++ b/lua/acf/shared/sounds/sweps.lua @@ -20,7 +20,7 @@ if SERVER then end else net.Receive("ACE_SWEPSounds", function() - ACE_SGunFire(net.ReadEntity(), net.ReadString(), net.ReadFloat()) + ACE_SGunFire(net.ReadEntity(), net.ReadString(), 1, net.ReadFloat()) end) end diff --git a/lua/acf/shared/sv_ace_networking.lua b/lua/acf/shared/sv_ace_networking.lua index 63ec2ded..b399a4d0 100644 --- a/lua/acf/shared/sv_ace_networking.lua +++ b/lua/acf/shared/sv_ace_networking.lua @@ -7,5 +7,5 @@ util.AddNetworkString( "ACE_ArmorSummary" ) util.AddNetworkString( "acf_smokewind" ) util.AddNetworkString( "ACE_CamOverride" ) util.AddNetworkString( "ACE_DPStatus" ) -util.AddNetworkString( "ACE_HasGodMode" ) util.AddNetworkString( "ACE_Scalable_Network" ) +util.AddNetworkString( "ACE_SendMessage" ) \ No newline at end of file diff --git a/lua/autorun/acf_globals.lua b/lua/autorun/acf_globals.lua index 5376d087..15dab4cc 100644 --- a/lua/autorun/acf_globals.lua +++ b/lua/autorun/acf_globals.lua @@ -3,7 +3,7 @@ ACF = ACF or {} ACF.AmmoTypes = {} ACF.MenuFunc = {} ACF.AmmoBlacklist = {} -ACF.Version = 485 -- ACE current version +ACF.Version = 488 -- ACE current version ACF.CurrentVersion = 0 -- just defining a variable, do not change ACF.Year = 2023 -- Current Year @@ -12,6 +12,7 @@ print("[ACE | INFO]- loading ACE. . .") ACE = ACE or {} ACE.ArmorTypes = {} +ACE.GSounds = {} ACF.Weapons = {} ACF.Classes = {} @@ -22,17 +23,17 @@ ACF.IdRounds = {} --Lookup tables so i can get rounds classes from clientsi Entity Limits ]]------------------------------ -CreateConVar("sbox_max_acf_gun", 24) -- Gun limit -CreateConVar("sbox_max_acf_rapidgun", 4) -- Guns like RACs, MGs, and ACs -CreateConVar("sbox_max_acf_largegun", 2) -- Guns with a caliber above 100mm -CreateConVar("sbox_max_acf_smokelauncher", 20) -- smoke launcher limit -CreateConVar("sbox_max_acf_ammo", 50) -- ammo limit -CreateConVar("sbox_max_acf_misc", 50) -- misc ents limit -CreateConVar("sbox_max_acf_rack", 12) -- Racks limit +CreateConVar("sbox_max_acf_gun", 24) -- Gun limit +CreateConVar("sbox_max_acf_rapidgun", 4) -- Guns like RACs, MGs, and ACs +CreateConVar("sbox_max_acf_largegun", 2) -- Guns with a caliber above 100mm +CreateConVar("sbox_max_acf_smokelauncher", 20) -- smoke launcher limit +CreateConVar("sbox_max_acf_ammo", 50) -- ammo limit +CreateConVar("sbox_max_acf_misc", 50) -- misc ents limit +CreateConVar("sbox_max_acf_rack", 12) -- Racks limit ---CreateConVar("sbox_max_acf_mines", 5) -- mines. Experimental +CreateConVar("acf_mines_max", 10) -- The mine limit CreateConVar("acf_meshvalue", 1) -CreateConVar("sbox_acf_restrictinfo", 1) -- 0=any, 1=owned +CreateConVar("sbox_acf_restrictinfo", 1) -- 0=any, 1=owned -- Cvars for legality checking CreateConVar( "acf_legalcheck", 1 , FCVAR_ARCHIVE) @@ -78,6 +79,8 @@ if CLIENT then CreateClientConVar( "ACFM_MissileLights", 0 ) --Should missiles emit light while their motors are burning? Looks nice but hits framerate. Set to 1 to enable, set to 0 to disable, set to another number to set minimum light-size. CreateClientConVar("acf_sens_irons", 0.5, true, false, "Reduce mouse sensitivity by this amount when zoomed in with iron sights on ACE SWEPs.", 0.01, 1) CreateClientConVar("acf_sens_scopes", 0.2, true, false, "Reduce mouse sensitivity by this amount when zoomed in with scopes on ACE SWEPs.", 0.01, 1) + CreateClientConVar( "acf_tinnitus", 1, true, false, "Allows the ear tinnitus effect to be applied when an explosive was detonated too close to your position, improving the inmersion during combat.", 0, 1 ) + CreateClientConVar( "acf_sound_volume", 100, true, false, "Adjusts the volume of explosions and gunshots.", 0, 100 ) end @@ -206,7 +209,17 @@ ACF.SlopeEffectFactor = 1.1 -- Sloped armor effectiveness: armor / cos(ang ACF.Spalling = 1 ACF.SpallMult = 1 --------------------------------------------------------------------- +---------------------------------- Particle colors ---------------------------------- + +ACE.DustMaterialColor = { + Concrete = Color(100,100,100,150), + Dirt = Color(117,101,70,150), + Sand = Color(200,180,116,150), + Glass = Color(255,255,255,50), +} + +-------------------------------------------------------------------------------------- + if ACF.AllowCSLua > 0 then AddCSLuaFile("autorun/translation/ace_translationpacks.lua") @@ -246,7 +259,7 @@ if SERVER then AddCSLuaFile("acf/client/cl_acfballistics.lua") AddCSLuaFile("acf/client/cl_acfmenu_gui.lua") AddCSLuaFile("acf/client/cl_acfrender.lua") - AddCSLuaFile("acf/client/cl_extension.lua") + AddCSLuaFile("acf/client/cl_soundbase.lua") AddCSLuaFile("acf/client/cl_acfmenu_missileui.lua") @@ -258,7 +271,7 @@ elseif CLIENT then include("acf/client/cl_acfballistics.lua") include("acf/client/cl_acfrender.lua") - include("acf/client/cl_extension.lua") + include("acf/client/cl_soundbase.lua") include("acf/client/cl_acfpermission.lua") include("acf/client/gui/cl_acfsetpermission.lua") @@ -331,16 +344,6 @@ if ACF.Year > 1989 then end - -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 - -ACE.Armors = list.Get("ACE_MaterialTypes") -ACE.GSounds = list.Get("ACESounds") - - game.AddDecal("GunShot1", "decals/METAL/shot5") -- Add the ACF tool category diff --git a/lua/autorun/client/cl_acfm_menuinject.lua b/lua/autorun/client/cl_acfm_menuinject.lua index 43809af0..6eb08316 100644 --- a/lua/autorun/client/cl_acfm_menuinject.lua +++ b/lua/autorun/client/cl_acfm_menuinject.lua @@ -3,6 +3,8 @@ include("acf/client/cl_acfmenu_missileui.lua") +local ACFEnts = ACF.Weapons + function SetMissileGUIEnabled(_, enabled, gundata) if enabled then @@ -30,7 +32,7 @@ function SetMissileGUIEnabled(_, enabled, gundata) local gunId = acfmenupanel.CData.CaliberSelect:GetValue() if gunId then - local guns = list.Get("ACFEnts").Guns + local guns = ACF.Weapons.Guns gun = guns[gunId] end @@ -78,7 +80,7 @@ function SetMissileGUIEnabled(_, enabled, gundata) local gunId = acfmenupanel.CData.CaliberSelect:GetValue() if gunId then - local guns = list.Get("ACFEnts").Guns + local guns = ACF.Weapons.Guns gun = guns[gunId] end @@ -246,23 +248,23 @@ function ModifyACFMenu(panel) oldAmmoSelect(panel, blacklist) acfmenupanel.CData.CaliberSelect.OnSelect = function( _ , _ , data ) - acfmenupanel.AmmoData["Data"] = acfmenupanel.WeaponData["Guns"][data]["round"] + acfmenupanel.AmmoData["Data"] = ACFEnts["Guns"][data]["round"] acfmenupanel:UpdateAttribs() acfmenupanel:UpdateAttribs() --Note : this is intentional - local gunTbl = acfmenupanel.WeaponData["Guns"][data] + local gunTbl = ACFEnts["Guns"][data] local class = gunTbl.gunclass - local Classes = list.Get("ACFClasses") + local Classes = ACF.Classes timer.Simple(0.01, function() SetMissileGUIEnabled( acfmenupanel, Classes.GunClass[class].type == "missile", gunTbl ) end) end local data = acfmenupanel.CData.CaliberSelect:GetValue() if data then - local gunTbl = acfmenupanel.WeaponData["Guns"][data] + local gunTbl = ACFEnts["Guns"][data] local class = gunTbl.gunclass - local Classes = list.Get("ACFClasses") + local Classes = ACF.Classes timer.Simple(0.01, function() SetMissileGUIEnabled( acfmenupanel, Classes.GunClass[class].type == "missile", gunTbl) end) end @@ -274,18 +276,15 @@ function ModifyACFMenu(panel) for _, node in pairs(rootNodes) do -- iterating though found folders - if node:GetText() == "Missiles" then --Missile folder is the one that we need - - gunsNode = node - break - - end - + if node:GetText() == "Missiles" then --Missile folder is the one that we need + gunsNode = node + break + end end if gunsNode then local classNodes = gunsNode.ChildNodes:GetChildren() - local gunClasses = list.Get("ACFClasses").GunClass + local gunClasses = ACF.Classes.GunClass for _, node in pairs(classNodes) do local gunNodeElement = node.ChildNodes diff --git a/lua/autorun/sh_ace_workarounds.lua b/lua/autorun/sh_ace_workarounds.lua index 6c0632b3..f0f8b3c5 100644 --- a/lua/autorun/sh_ace_workarounds.lua +++ b/lua/autorun/sh_ace_workarounds.lua @@ -57,85 +57,6 @@ if CLIENT then hook.Remove( "CalcVehicleView", "ACE_CalcVehicleView_Override") hook.Add( "CalcVehicleView", "ACE_CalcVehicleView_Override", ACE_CalcVehicleView) - do - - net.Receive("ACE_HasGodMode", function() - - local ply = LocalPlayer() - local Bool = net.ReadBool() - - ply.ACE_HasGodMode = Bool - - end) - - - end - -elseif SERVER then - - --excerpts taken from https://wiki.facepunch.com/gmod/Player:HasGodMode. Modified to use NET instead. SERVERSIDE - -- This is a workaround to issue: https://github.com/Facepunch/garrysmod-issues/issues/2038, where clientside doesnt know if the player is in godmode or not - -- Works with sbox_godmode convar too, then returning to its respective player god status if this command is turned off and custom godmodes are involved. - do - - local function SendGodStatus( bool, ply ) - - net.Start("ACE_HasGodMode") - net.WriteBool(bool) - - if IsValid(ply) then - net.Send( ply ) - else - net.Broadcast() - end - - end - - local PLAYER = FindMetaTable("Player") - - --To make sure we dont fuck up something else. - PLAYER.DefaultGodEnable = PLAYER.DefaultGodEnable or PLAYER.GodEnable - PLAYER.DefaultGodDisable = PLAYER.DefaultGodDisable or PLAYER.GodDisable - - function PLAYER:GodEnable() - - if GetConVar("sbox_godmode"):GetInt() <= 0 then - SendGodStatus( true, self ) - end - - self:DefaultGodEnable() - end - - function PLAYER:GodDisable() - - if GetConVar("sbox_godmode"):GetInt() <= 0 then - SendGodStatus( false, self ) - end - - self:DefaultGodDisable() - end - - cvars.RemoveChangeCallback( "sbox_godmode", "ACE_sbox_godmode" ) - cvars.AddChangeCallback("sbox_godmode", function(_, _, value ) - - if tonumber(value) > 0 then - - value = true - - SendGodStatus( value, nil ) - return - else - for _, ply in ipairs(player.GetHumans()) do -- we dont need to send client data to bots - - SendGodStatus( ply:HasGodMode(), ply ) - - end - end - - end, "ACE_sbox_godmode" ) - - end - end -- Workaround to issue: https://github.com/Facepunch/garrysmod-issues/issues/4142. Brought from ACF3 @@ -148,6 +69,7 @@ if not util.LegacyTraceLine then end function util.TraceLine(TraceData, ...) + if istable(TraceData) then TraceData.mins = Zero TraceData.maxs = Zero diff --git a/lua/autorun/wheel_list.lua b/lua/autorun/wheel_list.lua deleted file mode 100644 index fb21923e..00000000 --- a/lua/autorun/wheel_list.lua +++ /dev/null @@ -1,14 +0,0 @@ ---[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 index da1a4bf0..2a4b6a44 100644 --- a/lua/effects/acf_ap_impact/init.lua +++ b/lua/effects/acf_ap_impact/init.lua @@ -2,136 +2,91 @@ 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.Id = self.Ent:GetNWString( "AmmoType", "AP" ) - 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.Cal = self.Ent:GetNWFloat("Caliber", 2 ) - - self.Scale = math.max(self.Mass * (self.Velocity / 39.37) / 100,1) ^ 0.3 - - local Tr = {} - Tr.start = self.Origin - self.DirVec * 10 - Tr.endpos = self.Origin + self.DirVec * 10 - Tr.mins = Vector(0,0,0) - Tr.maxs = Vector(0,0,0) - - local SurfaceTr = util.TraceHull( Tr ) - - util.Decal("Impact.Concrete", SurfaceTr.StartPos, self.Origin + self.DirVec * 10 ) - - --debugoverlay.Cross( SurfaceTr.StartPos, 10, 3, Color(math.random(100,255),0,0) ) - --debugoverlay.Line( SurfaceTr.StartPos, self.Origin + self.DirVec * 10, 2 , Color(math.random(100,255),0,0) ) --this is crucial for subcaliber, this will boost the dust's size. - self.SubCalBoost = { - APDS = true, - APDSS = true, - APFSDS = true, - APFSDSS = true, - APCR = true, - HVAP = true - } +local SubCalBoost = { + APDS = true, + APDSS = true, + APFSDS = true, + APFSDSS = true, + APCR = true, + HVAP = true +} --the dust is for non-explosive rounds, so lets skip this - self.TypeIgnore = { - APHE = true, - APHECBC = true, - HE = true, - HEFS = true, - HESH = true, - HEAT = true, - HEATFS = true, - THEAT = true, - THEATFS = true - } - - self.Ignore = { - npc = true, - player = true - } - - -- 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 TypeIgnore = { + APHE = true, + APHECBC = true, + HE = true, + HEFS = true, + HESH = true, + HEAT = true, + HEATFS = true, + THEAT = true, + THEATFS = true +} + +local EntityFilter = { + player = true +} - --do this if we are dealing with non-explosive rounds. nil types are being created by HEAT, so skip it too - if not self.TypeIgnore[self.Id] and self.Id ~= nil and SurfaceTr.HitWorld or (IsValid(SurfaceTr.Entity) and self.Ignore[SurfaceTr.Entity:GetClass()]) then +function EFFECT:Init( data ) - local Mat = SurfaceTr.MatType --print(Mat) + self.AmmoCrate = data:GetEntity() + 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 - --concrete - local SmokeColor = Color(100,100,100,150) + self.Emitter = ParticleEmitter( self.Origin ) + self.Scale = math.max(self.Mass * (self.Velocity / 39.37) / 100,1) ^ 0.3 + self.Id = self.AmmoCrate:GetNWString( "AmmoType", "AP" ) + self.Caliber = self.AmmoCrate:GetNWFloat( "Caliber", 2 ) - -- Dirt - if Mat == 68 or Mat == 79 or Mat == 85 then - SmokeColor = Color(117,101,70,150) + local Tr = {} + Tr.start = self.Origin - self.DirVec * 10 + Tr.endpos = self.Origin + self.DirVec * 10 + local SurfaceTr = util.TraceLine( Tr ) - -- Sand - elseif Mat == 78 then - SmokeColor = Color(200,180,116,150) + --do this if we are dealing with non-explosive rounds. nil types are being created by HEAT, so skip it too + if not TypeIgnore[self.Id] and self.Id and SurfaceTr.HitWorld or (IsValid(SurfaceTr.Entity) and not EntityFilter[SurfaceTr.Entity:GetClass()]) then - -- Glass - elseif Mat == 89 then - SmokeColor = Color(255,255,255,50) - end + local Mat = SurfaceTr.MatType + local Material = ACE_GetMaterialName( Mat ) + local SmokeColor = ACE.DustMaterialColor[Material] or ACE.DustMaterialColor["Concrete"] - if Mat ~= 77 and Mat ~= 86 and Mat ~= 80 then - self:Dust( SmokeColor ) - else + if Material == "Metal" then self:Metal( SmokeColor ) + else + self:Dust( SmokeColor ) end end 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 + 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("Impact.Concrete", SurfaceTr.StartPos, self.Origin + self.DirVec * 10 ) + if self.Emitter then self.Emitter:Finish() end end function EFFECT:Dust( SmokeColor ) - --local PMul = self.ParticleMul local Vel = self.Velocity / 2500 local Mass = self.Mass - local HalfArea = (self.SubCalBoost[self.Id] and 0.75) or 1 - local ShellArea = 3.141 * (self.Cal / 2) * HalfArea - - --print(ShellArea) + local HalfArea = (SubCalBoost[self.Id] and 0.75) or 1 + local ShellArea = 3.141 * (self.Caliber / 2) * HalfArea --KE main formula local Energy = math.Clamp((((Mass * (Vel ^ 2)) / 2) / 2) * ShellArea, 4, math.max(ShellArea ^ 0.95, 4)) - --print(Energy) for _ = 1, 3 do local Dust = self.Emitter:Add("particle/smokesprites_000" .. math.random(1, 9), self.Origin - self.DirVec * 5) @@ -163,7 +118,7 @@ function EFFECT:Metal( SmokeColor ) local Mass = self.Mass --this is the size boost fo subcaliber rounds - local Boost = ( self.SubCalBoost[self.Id] and 2) or 1 + local Boost = ( SubCalBoost[self.Id] and 2) or 1 --KE main formula local Energy = math.max(((Mass * (Vel ^ 2)) / 2) * 0.005 * Boost, 2) diff --git a/lua/effects/acf_ap_penetration/init.lua b/lua/effects/acf_ap_penetration/init.lua index 2b171bdd..79237e1c 100644 --- a/lua/effects/acf_ap_penetration/init.lua +++ b/lua/effects/acf_ap_penetration/init.lua @@ -1,68 +1,61 @@ ---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. -----------------------------------------------------------]] + +local function DoubleSidedTraceResult( Effect ) + + local BackTraceFilter = {} + + local FrontTraceData = {} + FrontTraceData.start = Effect.Origin - Effect.DirVec:GetNormalized() + FrontTraceData.endpos = Effect.Origin + Effect.DirVec * 150 --IK that. I prefer big props dont have a exit point than simply faking it if it never was. + local FTrace = util.TraceLine(FrontTraceData) + + local BackTraceData = {} + BackTraceData.start = FrontTraceData.endpos + BackTraceData.endpos = FrontTraceData.start + BackTraceData.filter = function( ent ) if ent == FTrace.Entity then return true else table.insert(BackTraceFilter, ent) return false end end + local BTrace = util.TraceLine(BackTraceData) + + debugoverlay.Line(FrontTraceData.start, FTrace.HitPos , 5, Color(0,255,255)) + debugoverlay.Line(BackTraceData.start, BTrace.HitPos, 5, Color(191,255,0)) + + return FTrace, BTrace, BackTraceFilter +end + + 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.ParticleMul = math.Max( tonumber( LocalPlayer():GetInfo("acf_cl_particlemul") ) or 0, 0) - - self.Scale = math.max(self.Mass * (self.Velocity / 39.37) / 100, 1) ^ 0.3 - - local Tr = { } - Tr.start = self.Origin - self.DirVec * 20 - Tr.endpos = self.Origin + self.DirVec * 100 - Tr.mins = Vector(0,0,0) - Tr.maxs = Vector(0,0,0) - local Impact = util.TraceHull(Tr) --Trace to see if it will hit anything - self.Normal = Impact.HitNormal - - if IsValid(Impact.Entity) then - debugoverlay.Text(self.Origin - self.DirVec * 20, Impact.Entity:GetClass(), 5) + self.AmmoCrate = data:GetEntity() + 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.ParticleMul = math.Max( tonumber( LocalPlayer():GetInfo("acf_cl_particlemul") ) or 0, 0) + self.Scale = math.max(self.Mass * (self.Velocity / 39.37) / 100, 1) ^ 0.3 + self.Caliber = self.AmmoCrate:GetNWFloat( "Caliber", 10 ) + + local FTrace, BTrace, BackTraceFilter = DoubleSidedTraceResult( self ) + + util.Decal("Impact.Concrete", FTrace.StartPos, FTrace.HitPos + self.DirVec * 50, nil ) + util.Decal("Impact.Concrete", BTrace.StartPos, BTrace.HitPos - self.DirVec * 50, BackTraceFilter ) + + self.Normal = FTrace.HitNormal + if IsValid(FTrace.Entity) then + debugoverlay.Text(self.Origin - self.DirVec * 20, FTrace.Entity:GetClass(), 5) end - debugoverlay.Line(self.Origin - self.DirVec * 20, Impact.HitPos , 5, Color(0,255,255)) - - -- 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 - --print(Mat) - - self:Prop() - - ACE_SPen( self.Origin, self.Velocity, self.Mass ) + + + self:CreatePenetrationEffect() + ACE_SPenetration( self.Origin, self.Velocity, self.Mass ) if IsValid(self.Emitter) then self.Emitter:Finish() end end -function EFFECT:Prop() - - util.Decal("Impact.Concrete", self.Origin - self.DirVec * 50, self.Origin + self.DirVec * 50, self.Ent ) +function EFFECT:CreatePenetrationEffect() for _ = 0, self.Scale * self.ParticleMul do diff --git a/lua/effects/acf_ap_ricochet/init.lua b/lua/effects/acf_ap_ricochet/init.lua index 0bfc50b0..12700fa9 100644 --- a/lua/effects/acf_ap_ricochet/init.lua +++ b/lua/effects/acf_ap_ricochet/init.lua @@ -4,127 +4,96 @@ Initializes the effect. The data is a table of data which was passed from the server. -----------------------------------------------------------]] + +--this is crucial for subcaliber, this will boost the dust's size. +local SubCalBoost = { + APDS = true, + APDSS = true, + APFSDS = true, + APFSDSS = true, + APCR = true, + HVAP = true +} + +--the dust is for non-explosive rounds, so lets skip this. +--Note that APHE variants are not listed here but they still require it in case of rico vs ground. +local TypeIgnore = { + HE = true, + HEFS = true, + HESH = true, + HEAT = true, + HEATFS = true, + THEAT = true, + THEATFS = true +} + 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.Ent = data:GetEntity() -- the Ammocrate entity - self.Id = self.Ent:GetNWString( "AmmoType", "AP" ) - self.Scale = math.max(self.Mass * (self.Velocity / 39.37) / 100, 1) ^ 0.3 - self.ParticleMul = tonumber( LocalPlayer():GetInfo("acf_cl_particlemul") ) or 1 + 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.AmmoCrate = data:GetEntity() -- the Ammocrate entity + + self.Emitter = ParticleEmitter( self.Origin ) + self.Scale = math.max(self.Mass * (self.Velocity / 39.37) / 100, 1) ^ 0.3 + self.ParticleMul = tonumber( LocalPlayer():GetInfo("acf_cl_particlemul") ) or 1 + self.Id = self.AmmoCrate:GetNWString( "AmmoType", "AP" ) + self.Caliber = self.AmmoCrate:GetNWFloat("Caliber", 2 ) local Tr = {} Tr.start = self.Origin + self.DirVec Tr.endpos = self.Origin - self.DirVec * 12000 - Tr.mins = Vector(0,0,0) - Tr.maxs = Vector(0,0,0) - local SurfaceTr = util.TraceHull( Tr ) + local SurfaceTr = util.TraceLine( Tr ) - util.Decal("Impact.Concrete", self.Origin + self.DirVec * 10, self.Origin - self.DirVec * 10 ) - - self.Cal = self.Ent:GetNWFloat("Caliber", 2 ) - ACEE_SRico( self.Origin, self.Cal, self.Velocity, SurfaceTr.HitWorld ) - - --this is crucial for subcaliber, this will boost the dust's size. - self.SubCalBoost = { - APDS = true, - APDSS = true, - APFSDS = true, - APFSDSS = true, - APCR = true, - HVAP = true - } - - --the dust is for non-explosive rounds, so lets skip this. - --Note that APHE variants are not listed here but they still require it in case of rico vs ground. - local TypeIgnore = { - HE = true, - HEFS = true, - HESH = true, - HEAT = true, - HEATFS = true, - THEAT = true, - THEATFS = true - } + ACE_SRicochet( self.Origin, self.Caliber, self.Velocity, SurfaceTr.HitWorld ) --do this if we are dealing with non-explosive rounds if not TypeIgnore[self.Id] then - local Mat = SurfaceTr.MatType - - --concrete - local SmokeColor = Color(100,100,100,150) - - -- Dirt - if Mat == 68 or Mat == 79 or Mat == 85 then - SmokeColor = Color(117,101,70,150) - - -- Sand - elseif Mat == 78 then - SmokeColor = Color(200,180,116,150) + local Mat = SurfaceTr.MatType + local Material = ACE_GetMaterialName( Mat ) + local SmokeColor = ACE.DustMaterialColor[Material] or ACE.DustMaterialColor["Concrete"] - -- Glass - elseif Mat == 89 then - SmokeColor = Color(255,255,255,50) + if Material == "Metal" then + self:Metal( SmokeColor ) + else + self:Dust( SmokeColor ) + end end - if Mat ~= 77 and Mat ~= 86 and Mat ~= 80 then - self:Dust( SmokeColor ) - else - self:Metal() - end - - end - - 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("Impact.Concrete", self.Origin + self.DirVec * 10, self.Origin - self.DirVec * 10 ) if IsValid(self.Emitter) then self.Emitter:Finish() end end function EFFECT:Dust( SmokeColor ) - --local PMul = self.ParticleMul local Vel = self.Velocity / 2500 local Mass = self.Mass - local HalfArea = ( self.SubCalBoost[self.Id] and 0.75) or 1 - local ShellArea = 3.141 * (self.Cal / 2) * HalfArea - - --print(ShellArea) + local HalfArea = ( SubCalBoost[self.Id] and 0.75) or 1 + local ShellArea = 3.141 * (self.Caliber / 2) * HalfArea --KE main formula local Energy = math.Clamp((((Mass * (Vel ^ 2)) / 2) / 2) * ShellArea, 4, math.max(ShellArea ^ 0.95, 4)) / 2 - --print(Energy) - for _ = 1, 3 do - - local Dust = self.Emitter:Add( "particle/smokesprites_000" .. math.random(1,9), self.Origin ) - if (Dust) then - Dust:SetVelocity(VectorRand() * math.random( 20,30 * Energy) ) - Dust:SetLifeTime( 0 ) - Dust:SetDieTime( math.Rand( 1 , 2 ) * (Energy / 3) ) - Dust:SetStartAlpha( math.Rand( math.max(SmokeColor.a-20,10), SmokeColor.a ) ) - Dust:SetEndAlpha( 0 ) - Dust:SetStartSize( 5 * Energy ) - Dust:SetEndSize( 60 * Energy ) - Dust:SetRoll( math.Rand(150, 360) ) - Dust:SetRollDelta( math.Rand(-0.2, 0.2) ) - Dust:SetAirResistance( 350 ) - Dust:SetGravity( Vector( math.random(-5,5) * Energy, math.random(-5,5) * Energy, -70 ) ) - - Dust:SetColor( SmokeColor.r,SmokeColor.g,SmokeColor.b ) - end + local Dust = self.Emitter:Add( "particle/smokesprites_000" .. math.random(1,9), self.Origin ) + if (Dust) then + Dust:SetVelocity(VectorRand() * math.random( 20,30 * Energy) ) + Dust:SetLifeTime( 0 ) + Dust:SetDieTime( math.Rand( 1 , 2 ) * (Energy / 3) ) + Dust:SetStartAlpha( math.Rand( math.max(SmokeColor.a-20,10), SmokeColor.a ) ) + Dust:SetEndAlpha( 0 ) + Dust:SetStartSize( 5 * Energy ) + Dust:SetEndSize( 60 * Energy ) + Dust:SetRoll( math.Rand(150, 360) ) + Dust:SetRollDelta( math.Rand(-0.2, 0.2) ) + Dust:SetAirResistance( 350 ) + Dust:SetGravity( Vector( math.random(-5,5) * Energy, math.random(-5,5) * Energy, -70 ) ) + + Dust:SetColor( SmokeColor.r,SmokeColor.g,SmokeColor.b ) + end end end diff --git a/lua/effects/acf_bulleteffect/init.lua b/lua/effects/acf_bulleteffect/init.lua index a947e88a..1acf48e0 100644 --- a/lua/effects/acf_bulleteffect/init.lua +++ b/lua/effects/acf_bulleteffect/init.lua @@ -164,6 +164,21 @@ function EFFECT:Think() return false end +--Check if the crack is allowed to perform or not +local function CanBulletCrack( Bullet ) + + if Bullet.IsMissile then return false end + if Bullet.CrackCreated then return false end + if ACE_SInDistance( Bullet.InitialPos, 750 ) then return false end + if not ACE_SInDistance( Bullet.SimPos, math.max(Bullet.Caliber * 100 * ACE.CrackDistanceMultipler,250) ) then return false end + if Bullet.Impacted then return false end + + local SqrtSpeed = (Bullet.SimPos - Bullet.SimPosLast):LengthSqr() + if SqrtSpeed < 50 ^ 2 then return false end + + return true +end + function EFFECT:ApplyMovement( Bullet, Index ) local setPos = Bullet.SimPos @@ -176,15 +191,8 @@ function EFFECT:ApplyMovement( Bullet, Index ) self:SetPos( setPos ) --Moving the effect to the calculated position self:SetAngles( Bullet.SimFlight:Angle() ) - local Speed = math.abs((Bullet.SimPos - Bullet.SimPosLast):Length()) - --sonic crack sound - --horribly long if condition please fix without making a pyramid - if - not Bullet.CrackCreated and not Bullet.IsMissile and - ACE_SInDistance( Bullet.SimPos, math.max(Bullet.Caliber * 100 * ACE.CrackDistanceMultipler,250) ) and - not ACE_SInDistance( Bullet.InitialPos, 750 ) and Speed > 100 and not Bullet.Impacted - then + if CanBulletCrack( Bullet ) then ACE_SBulletCrack(Bullet, Bullet.Caliber) end else diff --git a/lua/effects/acf_cookoff/init.lua b/lua/effects/acf_cookoff/init.lua deleted file mode 100644 index 4dfb2187..00000000 --- a/lua/effects/acf_cookoff/init.lua +++ /dev/null @@ -1,70 +0,0 @@ ---[[--------------------------------------------------------- -Initializes the effect. The data is a table of data -which was passed from the server. ------------------------------------------------------------]] -function EFFECT:Init( data ) - - self.Scale = data:GetScale() * 5 - self.Entity:SetModel("models/dav0r/hoverball.mdl") - self.Entity:SetPos( data:GetOrigin() ) - self.Entity:PhysicsInit( SOLID_VPHYSICS ) - self.Entity:SetMoveType( MOVETYPE_VPHYSICS ) - self.Entity:SetSolid( SOLID_VPHYSICS ) - self.Entity:SetColor( Color(0,0,0,0 )) - self.Entity:SetRenderMode(RENDERMODE_TRANSALPHA) - --Msg("Effect Spawned/n") - - self.LifeTime = RealTime() + math.random(1, 2) - self.Emitter = ParticleEmitter( self.Entity:GetPos()) - - local phys = self.Entity:GetPhysicsObject() - if phys and phys:IsValid() then - phys:Wake() - phys:ApplyForceCenter( VectorRand() * math.random( 500 , 800 ) * self.Scale ) - --else - --Msg("Phys invalid/n") - end - -end - -function EFFECT:Think() - - local Smoke = self.Emitter:Add( "particle/smokesprites_000" .. math.random(1,9), self.Entity:GetPos()) - if (Smoke) then - Smoke:SetVelocity( VectorRand() * math.Rand(20,50) ) - Smoke:SetLifeTime( 0 ) - Smoke:SetDieTime( math.Rand( 2 , 4 ) ) - Smoke:SetStartAlpha( math.random( 20,80 ) ) - Smoke:SetEndAlpha( 0 ) - Smoke:SetStartSize( 4 * self.Scale / 2 ) - Smoke:SetEndSize( 8 * self.Scale / 2 ) - Smoke:SetRoll( math.Rand(0, 360) ) - Smoke:SetRollDelta( math.Rand(-0.2, 0.2) ) - Smoke:SetAirResistance( 50 ) - Smoke:SetGravity( Vector( math.Rand(0, 0) * self.Scale, math.Rand(0, 0) * self.Scale, 0 ) ) - Smoke:SetColor( 90,90,90 ) - end - - local Fire = self.Emitter:Add( "particles/flamelet" .. math.random(1,5), self.Entity:GetPos()) - if (Fire) then - Fire:SetVelocity( VectorRand() * math.Rand(50,100) ) - Fire:SetLifeTime( 0 ) - Fire:SetDieTime( 0.15 ) - Fire:SetStartAlpha( math.random( 100,150 ) ) - Fire:SetEndAlpha( 0 ) - Fire:SetStartSize( 1 * self.Scale / 2 ) - Fire:SetEndSize( 2 * self.Scale / 2 ) - Fire:SetRoll( math.Rand(0, 360) ) - Fire:SetRollDelta( math.Rand(-0.2, 0.2) ) - Fire:SetAirResistance( 100 ) - Fire:SetGravity( VectorRand() * self.Scale ) - Fire:SetColor( 255,255,255 ) - end - - return self.LifeTime > RealTime() -end - -function EFFECT:Render() - self.Entity:DrawModel() -end - diff --git a/lua/effects/acf_missilelaunch/init.lua b/lua/effects/acf_missilelaunch/init.lua index 8337ea2a..d70d87c9 100644 --- a/lua/effects/acf_missilelaunch/init.lua +++ b/lua/effects/acf_missilelaunch/init.lua @@ -4,36 +4,19 @@ which was passed from the server. -----------------------------------------------------------]] function EFFECT:Init( data ) - local Gun = data:GetEntity() - local Sound = Gun:GetNWString( "Sound" ) - local Propellant = data:GetScale() - local Attachment = data:GetAttachment() + local Missile = data:GetEntity() + local Rack = Missile:GetNWEntity( "Launcher", NULL ) - local Class = Gun:GetNWString( "Class" ) - --local RoundType = ACF.IdRounds[data:GetSurfaceProp()] + if IsValid(Rack) then + local Sound = Rack:GetNWString( "Sound", "" ) + local SoundPitch = Rack:GetNWInt( "SoundPitch", 100 ) - if CLIENT and not IsValidSound( Sound ) then - Sound = ACF.Classes["GunClass"][Class]["sound"] - end - - if Gun:IsValid() and Propellant > 0 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 + if not IsValidSound( Sound ) then + Sound = "acf_extra/airfx/rocket_fire2.wav" 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)) - local Muzzle = Gun:GetAttachment( Attachment ) or { Pos = Gun:GetPos(), Ang = Gun:GetAngles() } - Muzzle.Ang = (-Muzzle.Ang:Forward()):Angle() - ParticleEffect( ACF.Classes["GunClass"][Class]["muzzleflash"], Muzzle.Pos, Muzzle.Ang, Gun ) + ACE_SimpleSound( Sound, Missile:WorldSpaceCenter(), SoundPitch, 4000 ) end - - end diff --git a/lua/effects/acf_muzzleflash/init.lua b/lua/effects/acf_muzzleflash/init.lua index b10462e0..d1fd9ccc 100644 --- a/lua/effects/acf_muzzleflash/init.lua +++ b/lua/effects/acf_muzzleflash/init.lua @@ -9,12 +9,13 @@ function EFFECT:Init( data ) local Gun = data:GetEntity() if not IsValid(Gun) then return end - local Propellant = data:GetScale() - local ReloadTime = data:GetMagnitude() + local Propellant = data:GetScale() + local ReloadTime = data:GetMagnitude() - local Sound = Gun:GetNWString( "Sound", "" ) - local Class = Gun:GetNWString( "Class", "C" ) - local Caliber = Gun:GetNWInt( "Caliber", 1 ) * 10 + local Sound = Gun:GetNWString( "Sound", "" ) + local SoundPitch = Gun:GetNWInt( "SoundPitch", 100 ) + local Class = Gun:GetNWString( "Class", "C" ) + local Caliber = Gun:GetNWInt( "Caliber", 1 ) * 10 local MuzzleEffect = Gun:GetNWString( "Muzzleflash", "50cal_muzzleflash_noscale" ) --This tends to fail @@ -37,7 +38,7 @@ function EFFECT:Init( data ) if Propellant > 0 then - ACE_SGunFire( Gun, Sound, Propellant ) + ACE_SGunFire( Gun, Sound, SoundPitch, Propellant ) local Muzzle = Gun:GetAttachment( Gun:LookupAttachment(Attachment)) or { Pos = Gun:GetPos(), Ang = Gun:GetAngles() } diff --git a/lua/effects/acf_racklaunch/init.lua b/lua/effects/acf_racklaunch/init.lua new file mode 100644 index 00000000..9ef73119 --- /dev/null +++ b/lua/effects/acf_racklaunch/init.lua @@ -0,0 +1,20 @@ +--[[--------------------------------------------------------- +Initializes the effect. The data is a table of data +which was passed from the server. +-----------------------------------------------------------]] +function EFFECT:Init( _ ) +-- Blank for the future.... +end + +--[[--------------------------------------------------------- + THINK +-----------------------------------------------------------]] +function EFFECT:Think( ) + return false +end + +--[[--------------------------------------------------------- + Draw the effect +-----------------------------------------------------------]] +function EFFECT:Render() +end diff --git a/lua/effects/acf_radar_noise/init.lua b/lua/effects/acf_radar_noise/init.lua new file mode 100644 index 00000000..fa08b9ed --- /dev/null +++ b/lua/effects/acf_radar_noise/init.lua @@ -0,0 +1,32 @@ +--[[--------------------------------------------------------- +Initializes the effect. The data is a table of data +which was passed from the server. +-----------------------------------------------------------]] +function EFFECT:Init( data ) + + local Radar = data:GetEntity() + if IsValid(Radar) then + local Sound = Radar:GetNWString( "Sound", "" ) + local SoundPitch = Radar:GetNWInt( "SoundPitch", 100 ) + + if not IsValidSound( Sound ) then + Sound = ACFM.DefaultRadarSound + end + + ACE_SimpleSound( Sound, Radar:WorldSpaceCenter(), SoundPitch, 1000 ) + 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 index 037151fe..2c1735ad 100644 --- a/lua/effects/acf_scaled_explosion/init.lua +++ b/lua/effects/acf_scaled_explosion/init.lua @@ -114,7 +114,7 @@ function EFFECT:Init( data ) ACF_RenderLight( game.GetWorld():EntIndex(), self.Radius * 1800, Color(255, 128, 48), self.Origin, 0.1) end - ACEE_SBlast( self.Origin, self.Radius, self.HitWater, Ground.HitWorld ) + ACE_SBlast( self.Origin, self.Radius, self.HitWater, Ground.HitWorld ) if IsValid(self.Emitter) then self.Emitter:Finish() end end diff --git a/lua/effects/shaped_charge/init.lua b/lua/effects/shaped_charge/init.lua deleted file mode 100644 index d6817957..00000000 --- a/lua/effects/shaped_charge/init.lua +++ /dev/null @@ -1,104 +0,0 @@ ---[[--------------------------------------------------------- -Initializes the effect. The data is a table of data -which was passed from the server. ------------------------------------------------------------]] -function EFFECT:Init( data ) - - local Origin = data:GetOrigin() - local Direction = data:GetNormal() - local Scale = data:GetScale() - local Emitter = ParticleEmitter( Origin ) - - for _ = 0, 80 * Scale do - local particle = Emitter:Add( "particles/flamelet" .. math.random(1,5) , Origin) - if (particle) then - particle:SetVelocity( ( Direction * math.random(500,2000) + VectorRand() * 150 ) * Scale ) - particle:SetLifeTime( 0 ) - particle:SetDieTime( 0.5 ) - particle:SetStartAlpha( 255 ) - particle:SetEndAlpha( 10 ) - particle:SetStartSize( 5 ) - particle:SetEndSize( 15 ) - particle:SetAirResistance( 350 ) - particle:SetColor(255 , 255 , 255 ) - end - end - - for _ = 0, 20 * Scale do - - local Debris = Emitter:Add( "effects/fleck_tile" .. math.random(1,2), Origin ) - if (Debris) then - Debris:SetVelocity ( VectorRand() * math.random(400 * Scale,600 * Scale) ) - Debris:SetLifeTime( 0 ) - Debris:SetDieTime( math.Rand( 2 , 4 ) * Scale ) - Debris:SetStartAlpha( 255 ) - Debris:SetEndAlpha( 0 ) - Debris:SetStartSize( 2 ) - Debris:SetEndSize( 2 ) - Debris:SetRoll( math.Rand(0, 360) ) - Debris:SetRollDelta( math.Rand(-0.2, 0.2) ) - Debris:SetAirResistance( 100 ) - Debris:SetGravity( Vector( 0, 0, -650 ) ) - Debris:SetColor( 100,80,90 ) - end - end - - for _ = 0, 20 * Scale do - - local Embers = Emitter:Add( "particles/flamelet" .. math.random(1,5), Origin ) - if (Embers) then - Embers:SetVelocity ( VectorRand() * math.random(250 * Scale,400 * Scale) ) - Embers:SetLifeTime( 0 ) - Embers:SetDieTime( math.Rand( 2 , 4 ) * Scale ) - Embers:SetStartAlpha( 255 ) - Embers:SetEndAlpha( 0 ) - Embers:SetStartSize( 5 ) - Embers:SetEndSize( 5 ) - Embers:SetRoll( math.Rand(0, 360) ) - Embers:SetRollDelta( math.Rand(-0.2, 0.2) ) - Embers:SetAirResistance( 100 ) - Embers:SetGravity( Vector( 0, 0, -650 ) ) - Embers:SetColor( 100,80,90 ) - end - end - - for _ = 0, 20 * Scale do - - local Smoke = Emitter:Add( "particles/smokey", Origin ) - if (Smoke) then - Smoke:SetVelocity ( VectorRand() * math.random(150 * Scale,200 * Scale) ) - Smoke:SetLifeTime( 0 ) - Smoke:SetDieTime( math.Rand( 2 , 4 ) * Scale ) - Smoke:SetStartAlpha( 150 ) - Smoke:SetEndAlpha( 0 ) - Smoke:SetStartSize( 20 ) - Smoke:SetEndSize( 200 ) - Smoke:SetRoll( math.Rand(0, 360) ) - Smoke:SetRollDelta( math.Rand(-0.2, 0.2) ) - Smoke:SetAirResistance( 50 ) - Smoke:SetGravity( Vector( 0, 0, 100 ) ) - Smoke:SetColor( 100,80,90 ) - end - end - - if Emitter then Emitter:Finish() end -end - - ---[[--------------------------------------------------------- - THINK ------------------------------------------------------------]] -function EFFECT:Think( ) - return false -end - ---[[--------------------------------------------------------- - Draw the effect ------------------------------------------------------------]] -function EFFECT:Render() - - self.Entity:SetRenderMode( 0 ) - -end - - diff --git a/lua/entities/ace_antipersonelmine/init.lua b/lua/entities/ace_antipersonelmine/init.lua deleted file mode 100644 index 14458726..00000000 --- a/lua/entities/ace_antipersonelmine/init.lua +++ /dev/null @@ -1,112 +0,0 @@ -AddCSLuaFile("cl_init.lua") -AddCSLuaFile("shared.lua") - -include("shared.lua") - - -function ENT:Initialize() - - self:SetModel( "models/jaanus/wiretool/wiretool_range.mdl" ) - self:SetMoveType(MOVETYPE_VPHYSICS); - self:PhysicsInit(SOLID_VPHYSICS); - self:SetUseType(SIMPLE_USE); - self:SetSolid(SOLID_VPHYSICS); - local phys = self:GetPhysicsObject() - phys:SetMass(0.5) --4.1 kg mine, round down. - self:DrawShadow( false ) - self:SetMaterial( "models/props_canal/metalwall005b" ) - - self.TimeVar = 1 - self.MineState = 0 - self.phys = phys - self.LastTime = 0 - if ( IsValid( phys ) ) then phys:Wake() end -end - -function ENT:CanTool(ply, _, toolname) - if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and toolname == "remover" then - return true - end - - return false -end - -function ENT:CanProperty(ply, property) - if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and property == "remover" then - return true - end - - return false -end - -function ENT:Think() - - self.TimeVar = self.TimeVar + 1 - - if self.TimeVar >= 4 then - self.TimeVar = 0 - - --Mine not buried in ground. Mine will look for ground. - if self.MineState == 0 then - - local groundRanger = util.TraceLine( { - start = self:GetPos() + Vector(0,0,20), - endpos = self:GetPos() + Vector(0,0,-50), - collisiongroup = COLLISION_GROUP_WORLD, - filter = function( ent ) if ( ent:GetClass() == "prop_physics" ) then return true end end - } ) - - if groundRanger.Hit and groundRanger.HitWorld then - - self:SetPos(groundRanger.HitPos + Vector(0,0,-1.05)) - self:SetAngles(groundRanger.HitNormal:Angle() + Angle(90,0,0)) - self.MineState = 1 - self.phys:EnableMotion(false) - end - --print(groundRanger.Hit) - - --Mine activated and searching for enemy - elseif self.MineState == 1 then - - local triggerRanger = util.TraceHull( { - start = self:GetPos() + Vector(0,0,52), - endpos = self:GetPos() + Vector(0,0,87.1), - ignoreworld = true, - mins = Vector( -60, -60, -20 ), - maxs = Vector( 60, 60, 20 ), - mask = MASK_SHOT_HULL - } ) - - if triggerRanger.Hit then - - self:SetPos(self:GetPos() + self:GetUp() * 10) - self:Remove() - - local HEWeight = 2 - local Radius = HEWeight ^ 0.33 * 8 * 39.37 - - ACF_HE( self:GetPos() , Vector(0,0,1) , HEWeight , HEWeight * 0.5 , self.DamageOwner, nil, self) --0.5 is standard antipersonal mine - - local Flash = EffectData() - Flash:SetOrigin( self:GetPos() + self:GetUp() * 10 ) - Flash:SetNormal( Vector(0,0,-1) ) - Flash:SetRadius( Radius ) - util.Effect( "ACF_Scaled_Explosion", Flash ) - - - end - end - end -end - -function ENT:OnRemove() -end - - - - - - - - - diff --git a/lua/entities/ace_antipersonelmine/shared.lua b/lua/entities/ace_antipersonelmine/shared.lua deleted file mode 100644 index 73204762..00000000 --- a/lua/entities/ace_antipersonelmine/shared.lua +++ /dev/null @@ -1,6 +0,0 @@ -ENT.Type = "anim" -ENT.PrintName = "Mine-AntiPersonel" -ENT.Author = "RDC" -ENT.Category = "ACE-Explosives" -ENT.Spawnable = false -ENT.AdminSpawnable = false diff --git a/lua/entities/ace_antitankmine/cl_init.lua b/lua/entities/ace_antitankmine/cl_init.lua deleted file mode 100644 index 99d1bcbc..00000000 --- a/lua/entities/ace_antitankmine/cl_init.lua +++ /dev/null @@ -1,17 +0,0 @@ -include("shared.lua") - - - - - - - -function ENT:Draw() - - self:DrawModel() - - -end - - - diff --git a/lua/entities/ace_antitankmine/init.lua b/lua/entities/ace_antitankmine/init.lua deleted file mode 100644 index 7a42d359..00000000 --- a/lua/entities/ace_antitankmine/init.lua +++ /dev/null @@ -1,94 +0,0 @@ -AddCSLuaFile("cl_init.lua") -AddCSLuaFile("shared.lua") - -include("shared.lua") - - -function ENT:Initialize() - - self:SetModel( "models/maxofs2d/button_02.mdl" ) - self:SetMoveType(MOVETYPE_VPHYSICS); - self:PhysicsInit(SOLID_VPHYSICS); - self:SetUseType(SIMPLE_USE); - self:SetSolid(SOLID_VPHYSICS); - local phys = self:GetPhysicsObject() - phys:SetMass(8) - self:DrawShadow( false ) - self:SetMaterial( "models/props_canal/metalwall005b" ) - - self.TimeVar = 1 - self.MineState = 0 - self.phys = phys - self.LastTime = 0 - if ( IsValid( phys ) ) then phys:Wake() end -end - -function ENT:CanTool(ply, _, toolname) - if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and toolname == "remover" then - return true - end - - return false -end - -function ENT:CanProperty(ply, property) - if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and property == "remover" then - return true - end - - return false -end - -function ENT:Think() - - self.TimeVar = self.TimeVar + 1 - - if self.TimeVar >= 4 then - self.TimeVar = 0 - - if self.MineState == 0 then --Mine not buried in ground. Mine will look for ground. - - local groundRanger = util.TraceLine( { - start = self:GetPos() + Vector(0,0,20), - endpos = self:GetPos() + Vector(0,0,-50), - collisiongroup = COLLISION_GROUP_WORLD, - filter = function( ent ) if ( ent:GetClass() == "prop_physics" ) then return true end end - } ) - - if groundRanger.Hit and groundRanger.HitWorld then - self:SetPos(groundRanger.HitPos + Vector(0,0,-2.5)) - self:SetAngles(groundRanger.HitNormal:Angle() + Angle(90,0,0)) - self.MineState = 1 - self.phys:EnableMotion(false) - end - --print(groundRanger.Hit) - - elseif self.MineState == 1 then --Mine activated and searching for enemy - - local triggerRanger = util.TraceHull( { - start = self:GetPos() + Vector(0,0,52), - endpos = self:GetPos() + Vector(0,0,87.1), - ignoreworld = true, - mins = Vector( -60, -60, -20 ), - maxs = Vector( 60, 60, 20 ), - mask = MASK_SHOT_HULL - } ) - - if triggerRanger.Hit and not triggerRanger.Entity:IsPlayer() then - - local HEWeight = 250 - local Radius = HEWeight ^ 0.33 * 8 * 39.37 - - ACF_HE( self:GetPos() + self:GetUp() * 3, Vector(0,0,-1) , HEWeight , HEWeight * 0.2 , self.DamageOwner, self, self) --0.5 is standard antipersonal mine - - local Flash = EffectData() - Flash:SetOrigin( self:GetPos() + self:GetUp() * 3 ) - Flash:SetNormal( Vector(0,0,-1) ) - Flash:SetRadius( math.max( Radius, 1 ) ) - util.Effect( "ACF_Scaled_Explosion", Flash ) - - self:Remove() - end - end - end -end diff --git a/lua/entities/ace_antitankmine/shared.lua b/lua/entities/ace_antitankmine/shared.lua deleted file mode 100644 index 9fe366b3..00000000 --- a/lua/entities/ace_antitankmine/shared.lua +++ /dev/null @@ -1,6 +0,0 @@ -ENT.Type = "anim" -ENT.PrintName = "Mine-AntiTank" -ENT.Author = "RDC" -ENT.Category = "ACE-Explosives" -ENT.Spawnable = false -ENT.AdminSpawnable = false diff --git a/lua/entities/ace_boundingmine/cl_init.lua b/lua/entities/ace_boundingmine/cl_init.lua deleted file mode 100644 index 99d1bcbc..00000000 --- a/lua/entities/ace_boundingmine/cl_init.lua +++ /dev/null @@ -1,17 +0,0 @@ -include("shared.lua") - - - - - - - -function ENT:Draw() - - self:DrawModel() - - -end - - - diff --git a/lua/entities/ace_boundingmine/init.lua b/lua/entities/ace_boundingmine/init.lua deleted file mode 100644 index 3f2eaec6..00000000 --- a/lua/entities/ace_boundingmine/init.lua +++ /dev/null @@ -1,111 +0,0 @@ -AddCSLuaFile("cl_init.lua") -AddCSLuaFile("shared.lua") - -include("shared.lua") - - -function ENT:Initialize() - - self:SetModel( "models/cyborgmatt/capacitor_small.mdl" ) - self:SetMoveType(MOVETYPE_VPHYSICS); - self:PhysicsInit(SOLID_VPHYSICS); - self:SetUseType(SIMPLE_USE); - self:SetSolid(SOLID_VPHYSICS); - local phys = self:GetPhysicsObject() - phys:SetMass(4) --4.1 kg mine, round down. - - self.TimeVar = 1 - self.MineState = 0 - self.FuseTime = 0.5 - self.phys = phys - self.LastTime = 0 - self:DrawShadow( false ) - self:SetMaterial( "models/props_canal/canal_bridge_railing_01c" ) - - if ( IsValid( phys ) ) then phys:Wake() end -end - -function ENT:CanTool(ply, _, toolname) - if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and toolname == "remover" then - return true - end - - return false -end - -function ENT:CanProperty(ply, property) - if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and property == "remover" then - return true - end - - return false -end - -function ENT:Think() - - if self.MineState < 2 then --Mine actively jumping should have more tickrate for some reason. Imagine that. - - self.TimeVar = self.TimeVar + 1 - - if self.TimeVar >= 4 then - self.TimeVar = 0 - - if self.MineState == 0 then --Mine not buried in ground. Mine will look for ground. - - local groundRanger = util.TraceLine( { - start = self:GetPos() + Vector(0,0,20), - endpos = self:GetPos() + Vector(0,0,-50), - collisiongroup = COLLISION_GROUP_WORLD, - filter = function( ent ) if ( ent:GetClass() == "prop_physics" ) then return true end end - } ) - - if groundRanger.Hit and groundRanger.HitWorld then - - self:SetPos(groundRanger.HitPos + Vector(0,0,7.1)) - self:SetAngles(groundRanger.HitNormal:Angle() - Angle(90,0,0)) - self.MineState = 1 - self.phys:EnableMotion(false) - end - --print(groundRanger.Hit) - - elseif self.MineState == 1 then --Mine activated and searching for enemy - - local triggerRanger = util.TraceHull( { - start = self:GetPos() + Vector(0,0,52), - endpos = self:GetPos() + Vector(0,0,87.1), - ignoreworld = true, - mins = Vector( -120, -120, -20 ), - maxs = Vector( 120, 120, 20 ), - mask = MASK_SHOT_HULL - } ) - - if triggerRanger.Hit then - self:SetPos(self:GetPos() + self:GetUp() * -20) - self.MineState = 2 - self.phys:EnableMotion(true) - self.phys:ApplyForceCenter(self:GetUp() * self.phys:GetMass() * -230) - self.LastTime = CurTime() - self:EmitSound("weapons/amr/sniper_fire.wav", 75, 190, 1, CHAN_WEAPON ) - end - end - end - - else - - local curtime = CurTime() - self.FuseTime = self.FuseTime-(curtime-self.LastTime) - self.LastTime = CurTime() - - if self.FuseTime < 0 then - ACF_HE( self:GetPos() , Vector(0,0,1) , 5 , 0.1 , self.DamageOwner, nil, self) --0.5 is standard antipersonal mine - - local Flash = EffectData() - Flash:SetOrigin( self:GetPos() - self:GetUp() * 6 ) - Flash:SetNormal( Vector(0,0,-1) ) - Flash:SetRadius( math.max( 0.2, 1 ) ) - util.Effect( "ACF_Scaled_Explosion", Flash ) - - self:Remove() - end - end -end diff --git a/lua/entities/ace_boundingmine/shared.lua b/lua/entities/ace_boundingmine/shared.lua deleted file mode 100644 index 1122f90e..00000000 --- a/lua/entities/ace_boundingmine/shared.lua +++ /dev/null @@ -1,6 +0,0 @@ -ENT.Type = "anim" -ENT.PrintName = "Mine-Bounding" -ENT.Author = "RDC" -ENT.Category = "ACE-Explosives" -ENT.Spawnable = false -ENT.AdminSpawnable = false diff --git a/lua/entities/ace_flare/cl_init.lua b/lua/entities/ace_flare/cl_init.lua index 1dcd8e6c..64d0951c 100644 --- a/lua/entities/ace_flare/cl_init.lua +++ b/lua/entities/ace_flare/cl_init.lua @@ -19,7 +19,7 @@ function ENT:Draw() if CurTime() > self.LightUpdate and not self.StopLight then self.LightUpdate = CurTime() + 0.05 - ACF_RenderLight(self:EntIndex(), 1000, Color(255, 128, 48), self:GetPos()) + ACF_RenderLight(self:EntIndex(), 20000, Color(194, 145, 39), self:GetPos()) end end diff --git a/lua/entities/ace_irst/init.lua b/lua/entities/ace_irst/init.lua index 42edf1f2..2b3c36e2 100644 --- a/lua/entities/ace_irst/init.lua +++ b/lua/entities/ace_irst/init.lua @@ -10,7 +10,7 @@ function ENT:Initialize() self.LastStatusUpdate = CurTime() self.Active = false - self.Inputs = WireLib.CreateInputs( self, { "Active" } ) + self.Inputs = WireLib.CreateInputs( self, { "Active", "Cone" } ) self.Outputs = WireLib.CreateOutputs( self, {"Detected", "Owner [ARRAY]", "Position [ARRAY]", "Angle [ARRAY]", "EffHeat [ARRAY]", "ClosestToBeam"} ) self.OutputData = { Detected = 0, @@ -26,6 +26,9 @@ function ENT:Initialize() self.Heat = 21 -- Heat self.HeatAboveAmbient = 5 -- How many degrees above Ambient Temperature this irst will start to track? + self.MinViewCone = 3 + self.MaxViewCone = 45 + self.NextLegalCheck = ACF.CurTime + math.random(ACF.Legal.Min, ACF.Legal.Max) -- give any spawning issues time to iron themselves out self.Legal = true self.LegalIssues = "" @@ -36,6 +39,10 @@ function ENT:Initialize() end +local function SetConeParameter( IRST ) + IRST.inac = math.max( (IRST.Cone / 15) ^ 2, 2 ) print(IRST.inac) +end + function MakeACE_IRST(Owner, Pos, Angle, Id) if not Owner:CheckLimit("_acf_missileradar") then return false end @@ -58,8 +65,9 @@ function MakeACE_IRST(Owner, Pos, Angle, Id) IRST.ICone = radar.viewcone --Note: intentional. --Recorded initial cone IRST.Cone = IRST.ICone + SetConeParameter( IRST ) + IRST.SeekSensitivity = radar.SeekSensitivity - IRST.inac = radar.inaccuracy IRST.MinimumDistance = radar.mindist IRST.MaximumDistance = radar.maxdist @@ -109,6 +117,22 @@ end function ENT:TriggerInput( inp, value ) if inp == "Active" then self:SetActive((value ~= 0) and self.Legal) + elseif inp == "Cone" then + if value > 0 then + + self.Cone = math.Clamp(value / 2, self.MinViewCone ,self.MaxViewCone ) + + SetConeParameter( self ) + + --local curTime = CurTime() + --self:NextThink(curTime + 10) --You are not going from a wide to narrow beam in half a second deal with it. + else + self.Cone = self.ICone + end + + + + self:UpdateOverlayText() end end @@ -150,15 +174,15 @@ function ENT:GetWhitelistedEntsInCone() local ScanArray = ACE.contraptionEnts if table.IsEmpty(ScanArray) then return {} end - local WhitelistEnts = {} - local LOSdata = {} - local LOStr = {} + local WhitelistEnts = {} + local LOSdata = {} + local LOStr = {} - local IRSTPos = self:GetPos() + local IRSTPos = self:GetPos() - local entpos = Vector() - local difpos = Vector() - local dist = 0 + local entpos = Vector() + local difpos = Vector() + local dist = 0 for _, scanEnt in ipairs(ScanArray) do @@ -178,12 +202,12 @@ function ENT:GetWhitelistedEntsInCone() -- skip any ent far than maximum distance if dist > self.MaximumDistance then continue end - LOSdata.start = IRSTPos - LOSdata.endpos = entpos - LOSdata.collisiongroup = COLLISION_GROUP_WORLD - LOSdata.filter = function( ent ) if ( ent:GetClass() ~= "worldspawn" ) then return false end end - LOSdata.mins = vector_origin - LOSdata.maxs = LOSdata.mins + LOSdata.start = IRSTPos + LOSdata.endpos = entpos + LOSdata.collisiongroup = COLLISION_GROUP_WORLD + LOSdata.filter = function( ent ) if ( ent:GetClass() ~= "worldspawn" ) then return false end end + LOSdata.mins = vector_origin + LOSdata.maxs = LOSdata.mins LOStr = util.TraceHull( LOSdata ) @@ -215,13 +239,13 @@ function ENT:AcquireLock() self.ClosestToBeam = -1 local besterr = math.huge --Hugh mungus number - local entpos = Vector() - local difpos = Vector() - local nonlocang = Angle() - local ang = Angle() - local absang = Angle() - local errorFromAng = 0 - local dist = 0 + local entpos = Vector() + local difpos = Vector() + local nonlocang = Angle() + local ang = Angle() + local absang = Angle() + local errorFromAng = 0 + local dist = 0 local physEnt = NULL diff --git a/lua/entities/ace_antipersonelmine/cl_init.lua b/lua/entities/ace_mine/cl_init.lua similarity index 88% rename from lua/entities/ace_antipersonelmine/cl_init.lua rename to lua/entities/ace_mine/cl_init.lua index 99d1bcbc..1aee1f25 100644 --- a/lua/entities/ace_antipersonelmine/cl_init.lua +++ b/lua/entities/ace_mine/cl_init.lua @@ -1,16 +1,7 @@ include("shared.lua") - - - - - - function ENT:Draw() - self:DrawModel() - - end diff --git a/lua/entities/ace_mine/init.lua b/lua/entities/ace_mine/init.lua new file mode 100644 index 00000000..ec13e406 --- /dev/null +++ b/lua/entities/ace_mine/init.lua @@ -0,0 +1,243 @@ +AddCSLuaFile("cl_init.lua") +AddCSLuaFile("shared.lua") + +include("shared.lua") + +----------------------------------- The Mine Entity ----------------------------------- +do + + function ENT:Initialize() + + self.Ready = false + self.HasGround = false + self.PhysgunDisabled = true + + end + + local function ArmingMode( Mine ) + + local GroundTr = {} + GroundTr.start = Mine:GetPos() + Vector(0,0,5) + GroundTr.endpos = Mine:GetPos() + Vector(0,0,-Mine.setrange) + GroundTr.mask = MASK_NPCWORLDSTATIC + + local Trace = util.TraceLine(GroundTr) + + if Trace.Hit and Trace.HitWorld then + + if not Mine.HasGround then + + local Offset = Vector(0,0,Mine.digdepth) + local Position = Trace.HitPos + (Mine.GroundInverted and Offset or -Offset ) + local Angles = Trace.HitNormal:Angle() + (Mine.GroundInverted and Angle(-90,0,0) or Angle(90,0,0) ) + + Mine:SetPos( Position ) + Mine:SetAngles( Angles ) + Mine.physObj:EnableMotion(false) + Mine.HasGround = true + end + + timer.Simple(Mine.ArmingTime, function() + if IsValid(Mine) then + Mine.Ready = true + end + end) + + end + end + + local function ActiveMode( Mine ) + + local mins = Mine.triggermins + local maxs = Mine.triggermaxs + + local TriggerData = {} + TriggerData.start = Mine:WorldSpaceCenter() + TriggerData.endpos = TriggerData.start + TriggerData.ignoreworld = true + TriggerData.mins = mins + TriggerData.maxs = maxs + TriggerData.mask = MASK_SHOT_HULL + TriggerData.filter = function( ent ) if ( ent:GetClass() ~= "ace_mine" ) then return true end end + + debugoverlay.Box(TriggerData.start, TriggerData.mins, TriggerData.maxs, 0.5, Color(255,100,0, 50)) + + local TriggerTrace = util.TraceHull( TriggerData ) + + if TriggerTrace.Hit and Mine.IsJumper then + + if not Mine.HasJumped then + local FinalForce = Mine:GetUp() * Mine.physObj:GetMass() * (Mine.GroundInverted and -Mine.JumpForce or Mine.JumpForce) + + Mine.physObj:EnableMotion(true) + Mine.physObj:ApplyForceCenter( FinalForce ) + Mine:EmitSound("weapons/amr/sniper_fire.wav", 75, 190, 1, CHAN_WEAPON ) + + Mine.HasJumped = true + end + + timer.Simple(0.5, function() + if IsValid(Mine) and IsValid(Mine.physObj) then + Mine:Detonate() + + end + end) + + elseif TriggerTrace.Hit then + if not Mine.ignoreplayers or (Mine.ignoreplayers and not TriggerTrace.Entity:IsPlayer()) then + Mine:Detonate() + end + end + end + + function ENT:Think() + + --Mine will look for ground during the arming process + if not self.Ready then + ArmingMode( self ) + else + ActiveMode( self ) + end + end + + function ENT:Detonate() + if self.CustomMineDetonation then self.CustomMineDetonation( self ) return end + + self:Remove() + + local HEWeight = self.HEWeight + local FragMass = self.FragMass + local Radius = ACE_CalculateHERadius( HEWeight ) + local ExplosionOrigin = self:LocalToWorld(Vector(0,0,5)) + + ACF_HE( ExplosionOrigin, Vector(0,0,1), HEWeight, FragMass, self.DamageOwner, self, self) --0.5 is standard antipersonal mine + + local Flash = EffectData() + Flash:SetOrigin( ExplosionOrigin ) + Flash:SetNormal( Vector(0,0,-1) ) + Flash:SetRadius( Radius ) + util.Effect( "ACF_Scaled_Explosion", Flash ) + + end + + function ENT:CanTool(ply, _, toolname) + if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and toolname == "remover" then + return true + end + + return false + end + + function ENT:CanProperty(ply, property) + if ((CPPI and self:CPPICanTool(ply, "remover")) or (not CPPI)) and property == "remover" then + return true + end + + return false + end +end + +----------------------------------- Extra Initialization for the mine ----------------------------------- +do + + -- Initialize the necessary data to cache the mine counter per player. + function InitializePlayerMineCounter( ply ) + ACE.MineOwners = ACE.MineOwners or {} + ACE.MineOwners[ply] = {} + end + hook.Add( "PlayerInitialSpawn", "ACE_InitPlayerMineCounter", InitializePlayerMineCounter ) + + -- We dont need mines to stay on the map if the owner leaves. + function DeleteDisconnectPlayerMines( ply ) + if not ACE.MineOwners[ply] then return end + for _, mine in ipairs(ACE.MineOwners[ply]) do + mine:Remove() + end + end + hook.Add( "PlayerDisconnected", "Playerleave", DeleteDisconnectPlayerMines ) + +end + +----------------------------------- Mine Global Spawn function ----------------------------------- +do + local function CheckMineLimit( Owner ) + local limit = #ACE.MineOwners[Owner] < GetConVar("acf_mines_max"):GetInt() + print(#ACE.MineOwners[Owner], GetConVar("acf_mines_max"):GetInt(), limit) + return limit + end + + local function VerifyMineLimits(Owner) + + if not CheckMineLimit( Owner ) then + local OldMine = ACE.MineOwners[Owner][1] + if IsValid(OldMine) then + OldMine:Remove() + end + end + end + + local function AddMineToLimit( Owner, Mine ) + table.insert( ACE.MineOwners[Owner], Mine ) + print("Mine registered count to player " .. Owner:Nick() .. ": " .. #ACE.MineOwners[Owner] ) + end + + local MineTable = ACE.MineData + + function ACE_CreateMine( MineId, Pos, Angle, Owner ) + if not IsValid(Owner) then return end + + VerifyMineLimits(Owner) + + local Mine = ents.Create( "ace_mine" ) + if IsValid( Mine ) then + + local MineData = MineTable[MineId] + if not MineData then return end + + Mine.ArmingTime = MineData.armdelay or 0 + Mine.HEWeight = MineData.heweight or 0 + Mine.FragMass = MineData.fragmass or 0 + + Mine.weight = MineData.weight or 1 + Mine.ignoreplayers = MineData.ignoreplayers + Mine.IsJumper = MineData.shouldjump + Mine.JumpForce = MineData.shouldjump and MineData.jumpforce or nil + + Mine.setrange = MineData.setrange or 1 + Mine.triggermins = MineData.triggermins or vector_origin + Mine.triggermaxs = MineData.triggermaxs or vector_origin + + Mine.digdepth = MineData.digdepth or 0 + Mine.GroundInverted = MineData.groundinverted + + Mine.CustomMineDetonation = MineData.customdetonation + + Mine:CPPISetOwner(Entity(0)) + Mine.DamageOwner = Owner -- Done to avoid owners from manipulating the entity, but allowing the damage to be credited by him. + + Mine:SetPos( Pos ) + Mine:SetAngles( Angle ) + + Mine:SetModel( MineData.model ) + Mine:SetMaterial( MineData.material ) + Mine:SetColor( MineData.color or Color(255,255,255) ) + + Mine:SetMoveType(MOVETYPE_VPHYSICS); + Mine:PhysicsInit(SOLID_VPHYSICS); + Mine:SetSolid(SOLID_VPHYSICS); + Mine:Spawn() + + local physObj = Mine:GetPhysicsObject() + if IsValid(physObj) then + + Mine.physObj = physObj + physObj:SetMass(MineData.weight) + physObj:Wake() + end + + AddMineToLimit( Owner, Mine ) + + return Mine + end + end +end diff --git a/lua/entities/ace_mine/shared.lua b/lua/entities/ace_mine/shared.lua new file mode 100644 index 00000000..8d4921d5 --- /dev/null +++ b/lua/entities/ace_mine/shared.lua @@ -0,0 +1,6 @@ +ENT.Type = "anim" +ENT.PrintName = "Mine-Base-Entity" +ENT.Author = "RDC & Marty" +ENT.Category = "ACE-Explosives" +ENT.Spawnable = false +ENT.AdminSpawnable = false \ No newline at end of file diff --git a/lua/entities/ace_slammine/shared.lua b/lua/entities/ace_slammine/shared.lua index bd69aa62..64da0874 100644 --- a/lua/entities/ace_slammine/shared.lua +++ b/lua/entities/ace_slammine/shared.lua @@ -2,5 +2,5 @@ ENT.Type = "anim" ENT.PrintName = "Mine-SLAM" ENT.Author = "RDC" ENT.Category = "ACE-Explosives" -ENT.Spawnable = true -ENT.AdminSpawnable = true +ENT.Spawnable = false +ENT.AdminSpawnable = false diff --git a/lua/entities/ace_trackingradar/init.lua b/lua/entities/ace_trackingradar/init.lua index e1987bb5..dc70893b 100644 --- a/lua/entities/ace_trackingradar/init.lua +++ b/lua/entities/ace_trackingradar/init.lua @@ -19,21 +19,32 @@ function ENT:Initialize() self.Legal = true self.LegalIssues = "" + self.MinViewCone = 3 + self.MaxViewCone = 45 + self.ClosestToBeam = -1 self.Inputs = WireLib.CreateInputs( self, { "Active", "Cone" } ) self.Outputs = WireLib.CreateOutputs( self, {"Detected", "Owner [ARRAY]", "Position [ARRAY]", "Velocity [ARRAY]", "ClosestToBeam","IsJammed"} ) self.OutputData = { - Detected = 0, - Owner = {}, - Position = {}, - Velocity = {}, - ClosestToBeam = -1, - IsJammed = 0 + Detected = 0, + Owner = {}, + Position = {}, + Velocity = {}, + ClosestToBeam = -1, + IsJammed = 0 } end +local function SetConeParameters( Radar ) + + Radar.InaccuracyMul = (0.035 * (Radar.Cone / 15) ^ 2) * 0.2 + Radar.DPLRFAC = 65 - (Radar.Cone / 2) + Radar.ConeInducedGCTRSize = Radar.Cone * 10 + +end + function MakeACE_TrackingRadar(Owner, Pos, Angle, Id) if not Owner:CheckLimit("_acf_missileradar") then return false end @@ -50,14 +61,13 @@ function MakeACE_TrackingRadar(Owner, Pos, Angle, Id) Radar:SetAngles(Angle) Radar:SetPos(Pos) - Radar.Model = radar.model - Radar.Weight = radar.weight - Radar.ACFName = radar.name - Radar.ICone = radar.viewcone --Note: intentional. --Recorded initial cone - Radar.Cone = Radar.ICone - Radar.InaccuracyMul = (0.035 * (Radar.Cone / 15) ^ 2) * 0.2 - Radar.DPLRFAC = 65-(Radar.Cone / 2) - Radar.ConeInducedGCTRSize = Radar.Cone * 10 + Radar.Model = radar.model + Radar.Weight = radar.weight + Radar.ACFName = radar.name + Radar.ICone = radar.viewcone --Note: intentional. --Recorded initial cone + Radar.Cone = Radar.ICone + + SetConeParameters( Radar ) Radar.Id = Id Radar.Class = radar.class @@ -102,16 +112,15 @@ end function ENT:TriggerInput( inp, value ) if inp == "Active" then self:SetActive((value ~= 0) and self.Legal) - end - if inp == "Cone" then + elseif inp == "Cone" then if value > 0 then - self.Cone = math.Clamp(value / 2,3,45) + self.Cone = math.Clamp(value / 2, self.MinViewCone ,self.MaxViewCone ) + + SetConeParameters( self ) + local curTime = CurTime() self:NextThink(curTime + 10) --You are not going from a wide to narrow beam in half a second deal with it. - self.InaccuracyMul = (0.035 * (self.Cone / 15) ^ 2) * 0.2 -- +/- 5.3% 30 deg, +/- 1.3% 3 deg, +/- 3.5% 15 deg - self.DPLRFAC = 90-(self.Cone / 2) - self.ConeInducedGCTRSize = self.Cone * 10 else self.Cone = self.ICone end @@ -231,13 +240,11 @@ function ENT:Think() --Entity is within radar cone if (absang.p < self.Cone and absang.y < self.Cone) then - local LOStr = util.TraceHull( { + local LOStr = util.TraceLine( { start = thisPos ,endpos = entpos, collisiongroup = COLLISION_GROUP_WORLD, filter = function( ent ) if ( ent:GetClass() ~= "worldspawn" ) then return false end end, - mins = Vector( -0, -0, -0 ), - maxs = Vector( 0, 0, 0 ) }) --Hits anything in the world. diff --git a/lua/entities/acf_ammo/init.lua b/lua/entities/acf_ammo/init.lua index 5b2fcbe4..a1a1628d 100644 --- a/lua/entities/acf_ammo/init.lua +++ b/lua/entities/acf_ammo/init.lua @@ -327,10 +327,6 @@ function ENT:Update( ArgsTable ) local msg = "Ammo crate updated successfully!" - if not self:CPPICanTool(ArgsTable[1]) 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 diff --git a/lua/entities/acf_engine/init.lua b/lua/entities/acf_engine/init.lua index fcca053e..74f91e0e 100644 --- a/lua/entities/acf_engine/init.lua +++ b/lua/entities/acf_engine/init.lua @@ -64,13 +64,13 @@ end do local BackComp = { - ["Induction motor, Tiny"] = "Electric-Tiny-NoBatt", - ["Induction motor, Small, Standalone"] = "Electric-Small-NoBatt", - ["Induction motor, Medium, Standalone"] = "Electric-Medium-NoBatt", - ["Induction motor, Large, Standalone"] = "Electric-Large-NoBatt", + ["Induction motor, Tiny"] = "Electric-Tiny-NoBatt", + ["Induction motor, Small, Standalone"] = "Electric-Small-NoBatt", + ["Induction motor, Medium, Standalone"] = "Electric-Medium-NoBatt", + ["Induction motor, Large, Standalone"] = "Electric-Large-NoBatt", - ["AVDS-1790-9A"] = "24.8-V12", - ["AVDS-1790-1500"] = "27.0-V12" + ["AVDS-1790-9A"] = "24.8-V12", + ["AVDS-1790-1500"] = "27.0-V12" } function MakeACF_Engine(Owner, Pos, Angle, Id) @@ -92,31 +92,32 @@ do Engine:CPPISetOwner(Owner) Engine.Id = Id - Engine.Model = Lookup.model - Engine.SoundPath = Lookup.sound - Engine.Weight = Lookup.weight - Engine.PeakTorque = Lookup.torque - Engine.peakkw = Lookup.peakpower - Engine.PeakKwRPM = Lookup.peakpowerrpm - 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.Model = Lookup.model + Engine.Weight = Lookup.weight + Engine.PeakTorque = Lookup.torque + Engine.peakkw = Lookup.peakpower + Engine.PeakKwRPM = Lookup.peakpowerrpm + 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.TorqueCurve = Lookup.torquecurve or ACF.GenericTorqueCurves[Engine.EngineType] - Engine.RequiresFuel = Lookup.requiresfuel - Engine.SoundPitch = Lookup.pitch or 1 - Engine.SpecialHealth = true - Engine.SpecialDamage = true - Engine.TorqueMult = 1 - Engine.FuelTank = 0 - Engine.Heat = ACE.AmbientTemp + Engine.IsTrans = Lookup.istrans -- driveshaft outputs to the side + Engine.FuelType = Lookup.fuel or "Petrol" + Engine.EngineType = Lookup.enginetype or "GenericPetrol" + Engine.TorqueCurve = Lookup.torquecurve or ACF.GenericTorqueCurves[Engine.EngineType] + Engine.RequiresFuel = Lookup.requiresfuel + Engine.SoundPath = Lookup.sound + Engine.DefaultSound = Engine.SoundPath + Engine.SoundPitch = Lookup.pitch or 100 + Engine.SpecialHealth = true + Engine.SpecialDamage = true + Engine.TorqueMult = 1 + Engine.FuelTank = 0 + Engine.Heat = ACE.AmbientTemp Engine.TorqueScale = ACF.TorqueScale[Engine.EngineType] @@ -167,10 +168,6 @@ function ENT:Update( ArgsTable ) return false, "Turn off the engine before updating it!" end - if not self:CPPICanTool(ArgsTable[1]) 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 = EngineTable[Id] @@ -188,29 +185,30 @@ function ENT:Update( ArgsTable ) end end - self.Id = Id - self.SoundPath = Lookup.sound - self.Weight = Lookup.weight - self.PeakTorque = Lookup.torque - self.peakkw = Lookup.peakpower - self.PeakKwRPM = Lookup.peakpowerrpm - 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.Id = Id + self.Weight = Lookup.weight + self.PeakTorque = Lookup.torque + self.peakkw = Lookup.peakpower + self.PeakKwRPM = Lookup.peakpowerrpm + 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.SoundPath = Lookup.sound + self.DefaultSound = self.SoundPath + self.SoundPitch = Lookup.pitch or 100 + self.SpecialHealth = true + self.SpecialDamage = true + self.TorqueMult = self.TorqueMult or 1 + self.FuelTank = 0 self.TorqueScale = ACF.TorqueScale[self.EngineType] @@ -642,7 +640,7 @@ function ENT:CalcRPM() --Wire_TriggerOutput(self, "EngineHeat", self.Heat) --Definately an RPM calculation if self.Sound then - self.Sound:ChangePitch( math.min( 20 + (SmoothRPM * self.SoundPitch) / 50, 255 ), 0 ) + self.Sound:ChangePitch( math.min( 20 + (SmoothRPM * (self.SoundPitch / 100)) / 50, 255 ), 0 ) self.Sound:ChangeVolume( 0.25 + (0.1 + 0.9 * ((SmoothRPM / self.LimitRPM) ^ 1.5)) * self.Throttle / 1.5, 0 ) end diff --git a/lua/entities/acf_fueltank/init.lua b/lua/entities/acf_fueltank/init.lua index c2119b3f..92eb611a 100644 --- a/lua/entities/acf_fueltank/init.lua +++ b/lua/entities/acf_fueltank/init.lua @@ -125,14 +125,14 @@ function ENT:ACF_OnDamage( Entity, Energy, FrArea, Angle, Inflictor, _, Type ) - local ExplodeChance = (1-(self.Fuel / self.Capacity)) ^ 0.75 --chance to explode from fumes in tank, less fuel = more explodey --it's gonna blow - if math.Rand(0,1) < (ExplodeChance + Ratio) then + if math.Rand(0, 1.2) < (ExplodeChance + Ratio) then if hook.Run( "ACF_FuelExplode", self ) == false then return HitRes end self.Inflictor = Inflictor self.Exploding = true - timer.Simple(math.random(0.1,1), function() + timer.Simple(math.Rand(0.1, 1), function() if IsValid(self) then ACF_ScaledExplosion( self ) end @@ -140,7 +140,9 @@ function ENT:ACF_OnDamage( Entity, Energy, FrArea, Angle, Inflictor, _, Type ) - 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 + if self.FuelType ~= "Electric" then + self.Leaking = self.Leaking + self.Fuel * ((HitRes.Damage / self.ACF.Health) ^ 1.5) * 0.25 + end end return HitRes @@ -358,7 +360,7 @@ function ENT:UpdateOverlayText() if self.FuelType == "Electric" then - text = text .. "\nCurrent Charge Levels:" + text = text .. "\nCurrent Charge Level:" text = text .. "\n- " .. math.Round( self.Fuel, 1 ) .. " / " .. math.Round( self.Capacity, 1 ) .. " kWh" text = text .. "\n- " .. math.Round( self.Fuel * 3.6, 1 ) .. " / " .. math.Round( self.Capacity * 3.6, 1) .. " MJ" @@ -369,6 +371,10 @@ function ENT:UpdateOverlayText() text = text .. "\n- " .. math.Round( self.Fuel * 0.264172, 1 ) .. " / " .. math.Round( self.Capacity * 0.264172, 1 ) .. " gallons" --text = text .. "\nFuel Remaining: " .. math.Round( self.Fuel, 1 ) .. " liters / " .. math.Round( self.Fuel * 0.264172, 1 ) .. " gallons" + + if self.Leaking > 0 then + text = text .. "\n- Leaking: " .. math.Round(self.Leaking, 1) .. " liters per second" + end end if not self.Legal then @@ -391,7 +397,7 @@ function ENT:UpdateFuelMass() --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) + self.NextMassUpdate = CurTime() + math.Rand(10, 15) local phys = self:GetPhysicsObject() if (phys:IsValid()) then phys:SetMass( self.Mass ) @@ -406,10 +412,6 @@ function ENT:Update( ArgsTable ) local Feedback = "" - if not self:CPPICanTool(ArgsTable[1]) 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 _, Engine in pairs( self.Master ) do if Engine:IsValid() then @@ -460,23 +462,34 @@ function ENT:Think() 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 ) + self:NextThink( CurTime() + 1 ) end --refuelling if self.Active and self.SupplyFuel and self.Fuel > 0 and self.Legal then + self:NextThink(CurTime()) 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 and (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 + local exchange = ((self.FuelType == "Electric") and 1 or 15) / 200 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) + if not Tank.PlayedSound and CurTime() > (Tank.NextSoundTime or 0) then + sound.Play("ambient/energy/newspark04.wav", Tank:GetPos(), 75, 100, 0.5) + Tank.PlayedSound = true + Tank.NextSoundTime = CurTime() + 1 -- Adjust the delay time (in seconds) as needed + end else - sound.Play("vehicles/jetski/jetski_no_gas_start.wav",Tank:GetPos(),75,120,0.5) + if CurTime() > (Tank.NextSoundTime or 0) then + sound.Play("vehicles/jetski/jetski_no_gas_start.wav", Tank:GetPos(), 75, 120, 0.5) + Tank.NextSoundTime = CurTime() + 1 -- Adjust the delay time (in seconds) as needed + end end end end diff --git a/lua/entities/acf_gearbox/init.lua b/lua/entities/acf_gearbox/init.lua index 0042c38e..16583467 100644 --- a/lua/entities/acf_gearbox/init.lua +++ b/lua/entities/acf_gearbox/init.lua @@ -213,10 +213,6 @@ 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 not self:CPPICanTool(ArgsTable[1]) 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 GearboxData = GearboxTable[Id] diff --git a/lua/entities/acf_glatgm/init.lua b/lua/entities/acf_glatgm/init.lua index f57f3db4..be0c89b8 100644 --- a/lua/entities/acf_glatgm/init.lua +++ b/lua/entities/acf_glatgm/init.lua @@ -52,12 +52,19 @@ function ENT:Initialize() -- how far off the forward offset is for the targeting position self.offsetLength = self.velocity * self.secondsOffset + --You need to declare the CPPI owner before seeing if the optic's owner is equal to the GLATGM's owner! + self:CPPISetOwner(self.BulletData.Owner) + --Gets the Closest computer to spawned missile to override gunĀ“s guidance --Dont bother at using this if the table is empty - if not table.IsEmpty( ACE.Opticals ) then - for _, Optical in pairs( ACE.Opticals ) do + if next(ACE.Opticals) then - if not IsValid(Optical) then continue end + for _, Optical in pairs(ACE.Opticals) do + --print("Looking for computer...") + + if not IsValid(Optical) then + continue + end --Range: 250. Note im using squared distance. So 250 ^ 2 means distance is 250 if Optical:GetPos():DistToSqr(self:GetPos()) < 250 ^ 2 and Optical:CPPIGetOwner() == self:CPPIGetOwner() then @@ -69,13 +76,9 @@ function ENT:Initialize() self.Optic = true end - - end end - self:CPPISetOwner(self.BulletData.Owner) - --Rocket Trail effect timer.Simple(0.1,function() ParticleEffectAttach("Rocket_Smoke_Trail",4, self,1) end) diff --git a/lua/entities/acf_gun/cl_init.lua b/lua/entities/acf_gun/cl_init.lua index bdbaef29..091bde78 100644 --- a/lua/entities/acf_gun/cl_init.lua +++ b/lua/entities/acf_gun/cl_init.lua @@ -86,7 +86,7 @@ function ACFGunGUICreate( Table ) GunDisplay.LayoutEntity = function() end acfmenupanel.CustomDisplay:AddItem( GunDisplay ) - local GunClass = list.Get("ACFClasses").GunClass[Table.gunclass] + local GunClass = ACF.Classes.GunClass[Table.gunclass] acfmenupanel:CPanelText("ClassDesc", GunClass.desc) acfmenupanel:CPanelText("GunDesc", Table.desc) acfmenupanel:CPanelText("Caliber", "Caliber : " .. (Table.caliber * 10) .. "mm") diff --git a/lua/entities/acf_gun/init.lua b/lua/entities/acf_gun/init.lua index 2a37cbed..8c171826 100644 --- a/lua/entities/acf_gun/init.lua +++ b/lua/entities/acf_gun/init.lua @@ -7,64 +7,68 @@ local GunClasses = ACF.Classes.GunClass local GunTable = ACF.Weapons.Guns +--The distances these ents would have if its caliber was 10mm. Incremented by caliber size. +local CrewLinkDistBase = 100 +local AmmoLinkDistBase = 512 + function ENT:Initialize() - self.ReloadTime = 1 - - self.FirstLoad = true - self.Ready = true - self.Firing = nil - self.Reloading = nil - self.NextFire = 0 - self.LastSend = 0 - self.LastLoadDuration = 0 - self.NextLegalCheck = ACF.CurTime + math.random(ACF.Legal.Min, ACF.Legal.Max) -- give any spawning issues time to iron themselves out - self.Legal = true - self.LegalIssues = "" - self.FuseTime = 0 - self.OverrideFuse = false -- Override disabled by default - self.ROFLimit = 0 -- Used for selecting firerate - - self.IsMaster = true -- needed? - self.AmmoLink = {} - self.CrewLink = {} - self.HasGunner = false - self.LoaderCount = 0 - self.CurAmmo = 1 - self.Sequence = 1 - self.GunClass = "MG" - - self.Heat = ACE.AmbientTemp - self.IsOverheated = false - - self.BulletData = {} - self.BulletData.Type = "Empty" - self.BulletData.PropMass = 0 - self.BulletData.ProjMass = 0 - - self.Inaccuracy = 1 - self.LastThink = 0 + self.ReloadTime = 1 + + self.FirstLoad = true + self.Ready = true + self.Firing = nil + self.Reloading = nil + self.NextFire = 0 + self.LastSend = 0 + self.LastLoadDuration = 0 + self.NextLegalCheck = ACF.CurTime + math.random(ACF.Legal.Min, ACF.Legal.Max) -- give any spawning issues time to iron themselves out + self.Legal = true + self.LegalIssues = "" + self.FuseTime = 0 + self.OverrideFuse = false -- Override disabled by default + self.ROFLimit = 0 -- Used for selecting firerate + + self.IsMaster = true -- needed? + self.AmmoLink = {} + self.CrewLink = {} + self.HasGunner = false + self.LoaderCount = 0 + self.CurAmmo = 1 + self.Sequence = 1 + self.GunClass = "MG" + + self.Heat = ACE.AmbientTemp + self.IsOverheated = false + + self.BulletData = {} + self.BulletData.Type = "Empty" + self.BulletData.PropMass = 0 + self.BulletData.ProjMass = 0 + + self.Inaccuracy = 1 + self.LastThink = 0 end do local Inputs = { - Fire = "Fire (Shoots a bullet if loaded. Hold to keep shooting.)", - Unload = "Unload (Unloads the current shell from the gun. Leaving the gun empty.)", - Reload = "Reload (Reloads the current weapon, according to the active ammo it has.)", - FuseTime = "Fuse Time (Defines the required time for shell self-detonation in seconds. \nThis only work with SM, HE & HEAT rounds. \nNote that this is not really accurate.)", - ROFLimit = "ROFLimit (Adjusts the Gun's Rate of Fire. \nNote that setting this to 0 WILL disable overriding! \nIf you want lower rof, use values like 0.1.)", + Fire = "Fire (Shoots a bullet if loaded. Hold to keep shooting.)", + Unload = "Unload (Unloads the current shell from the gun. Leaving the gun empty.)", + Reload = "Reload (Reloads the current weapon, according to the active ammo it has.)", + FuseTime = "Fuse Time (Defines the required time for shell self-detonation in seconds. \nThis only work with SM, HE & HEAT rounds. \nNote that this is not really accurate.)", + ROFLimit = "ROFLimit (Adjusts the Gun's Rate of Fire. \nNote that setting this to 0 WILL disable overriding! \nIf you want lower rof, use values like 0.1.)", } local Outputs = { - Ready = "Ready (Returns if the gun is ready to fire.)", - AmmoCount = "AmmoCount (Returns the total ammo this gun can shoot.)", - Entity = "Entity [ENTITY]", - ShotsLeft = "Shots Left (Returns the number of shots in the gun.)", - FireRate = "Fire Rate (Returns the Rate of Fire of this gun)", - MuzzleWeight = "Muzzle Weight (Returns the muzzle weight)", - MuzzleVelocity = "Muzzle Velocity (Returns the muzzle velocity)" , - Heat = "Heat (Returns the gun's temperature.)", - OverHeat = "OverHeat (Is the gun overheating?)" + Ready = "Ready (Returns if the gun is ready to fire.)", + AmmoCount = "AmmoCount (Returns the total ammo this gun can shoot.)", + Entity = "Entity [ENTITY]", + ShotsLeft = "Shots Left (Returns the number of shots in the gun.)", + FireRate = "Fire Rate (Returns the Rate of Fire of this gun)", + MuzzleWeight = "Muzzle Weight (Returns the muzzle weight)", + MuzzleVelocity = "Muzzle Velocity (Returns the muzzle velocity)" , + Heat = "Heat (Returns the gun's temperature.)", + OverHeat = "OverHeat (Is the gun overheating?)" } local Inputs_Fuse = { @@ -105,12 +109,12 @@ do --List of ids which no longer stay on ACE. Useful to replace them with the closest counterparts local BackComp = { - ["20mmHRAC"] = "20mmRAC", - ["30mmHRAC"] = "30mmRAC", - ["105mmSB"] = "100mmSBC", - ["120mmSB"] = "120mmSBC", - ["140mmSB"] = "140mmSBC", - ["170mmSB"] = "170mmSBC" + ["20mmHRAC"] = "20mmRAC", + ["30mmHRAC"] = "30mmRAC", + ["105mmSB"] = "100mmSBC", + ["120mmSB"] = "120mmSBC", + ["140mmSB"] = "140mmSBC", + ["170mmSB"] = "170mmSBC" } local rapidgun = { @@ -154,13 +158,13 @@ do Gun:SetPos(Pos) Gun:Spawn() Gun:CPPISetOwner(Owner) - Gun.Id = Id - Gun.Caliber = Lookup.caliber - Gun.Model = Lookup.model - Gun.Mass = Lookup.weight - Gun.Class = Lookup.gunclass - Gun.Heat = ACE.AmbientTemp - Gun.LinkRangeMul = math.max(Gun.Caliber / 10,1) ^ 1.2 + Gun.Id = Id + Gun.Caliber = Lookup.caliber + Gun.Model = Lookup.model + Gun.Mass = Lookup.weight + Gun.Class = Lookup.gunclass + Gun.Heat = ACE.AmbientTemp + Gun.LinkRangeMul = math.max(Gun.Caliber / 10,1) ^ 1.2 Gun.noloaders = ClassData.noloader or nil @@ -207,13 +211,15 @@ do Gun.MagReload = math.max(Gun.MagReload, Lookup.magreload ) end - Gun.MinLengthBonus = 0.5 * 3.1416 * (Gun.Caliber / 2) ^ 2 * Lookup.round.maxlength + Gun.MinLengthBonus = 0.5 * 3.1416 * (Gun.Caliber / 2) ^ 2 * Lookup.round.maxlength - Gun.Muzzleflash = Lookup.muzzleflash or ClassData.muzzleflash - Gun.RoFmod = ClassData.rofmod - Gun.RateOfFire = 1 --updated when gun is linked to ammo - Gun.Sound = Lookup.sound or ClassData.sound - Gun.AutoSound = ClassData.autosound and (Lookup.autosound or ClassData.autosound) or nil + Gun.Muzzleflash = Lookup.muzzleflash or ClassData.muzzleflash + Gun.RoFmod = ClassData.rofmod + Gun.RateOfFire = 1 --updated when gun is linked to ammo + Gun.Sound = Lookup.sound or ClassData.sound + Gun.DefaultSound = Gun.Sound + Gun.SoundPitch = 100 + Gun.AutoSound = ClassData.autosound and (Lookup.autosound or ClassData.autosound) or nil Gun:SetNWInt( "Caliber", Gun.Caliber ) Gun:SetNWString( "WireName", Lookup.name ) @@ -221,6 +227,7 @@ do Gun:SetNWString( "ID", Gun.Id ) Gun:SetNWString( "Muzzleflash", Gun.Muzzleflash ) Gun:SetNWString( "Sound", Gun.Sound ) + Gun:SetNWInt( "SoundPitch", Gun.SoundPitch ) Gun:SetModel( Gun.Model ) @@ -300,6 +307,22 @@ function ENT:UpdateOverlayText() end +local function IsInRetDist( enta, entb, Distance ) + if not IsValid(enta) or not IsValid(entb) then return end + return ACE_InDist( enta:GetPos(), entb:GetPos(), Distance ) +end + +local BreakSoundTbl = { + ace_crewseat_gunner = "physics/metal/metal_canister_impact_hard", + ace_crewseat_loader = "physics/metal/metal_canister_impact_hard", + acf_ammo = "physics/metal/metal_box_impact_bullet", +} + +local function BreakGunLink( Gun, LinkedEnt ) + Gun:Unlink( LinkedEnt ) + Gun:EmitSound( (BreakSoundTbl[LinkedEnt:GetClass()] or "physics/metal/metal_box_impact_bullet" ) .. tostring(math.random(1, 3)) .. ".wav",100,100) +end + function ENT:Link( Target ) if not IsValid( Target ) then @@ -318,7 +341,7 @@ function ENT:Link( Target ) end --Don't link if it's too far from this gun - if RetDist( self, Target ) > 100 * self.LinkRangeMul then + if not IsInRetDist( self, Target, CrewLinkDistBase * self.LinkRangeMul ) then return false, "That crewseat is too far to be linked to this gun!" end @@ -345,7 +368,7 @@ function ENT:Link( Target ) end --Don't link if it's too far from this gun - if RetDist( self, Target ) > 100 * self.LinkRangeMul then + if not IsInRetDist( self, Target, CrewLinkDistBase * self.LinkRangeMul ) then return false, "That crewseat is too far to be linked to this gun!" end @@ -371,9 +394,16 @@ function ENT:Link( Target ) --Ammo Link elseif Target:GetClass() == "acf_ammo" then - -- Don't link if it's not the right ammo type - if Target.BulletData.Id ~= self.Id then - return false, "Wrong ammo type!" + -- Don't link if it's already linked + for _, v in pairs( self.AmmoLink ) do + if v == Target then + return false, "That crate is already linked to this gun!" + end + end + + -- Dont't link if it's too far from this gun + if not IsInRetDist( self, Target, AmmoLinkDistBase * self.LinkRangeMul ) then + return false, "That crate is too far to be connected with this gun!" end -- Don't link if it's a refill crate @@ -381,6 +411,11 @@ function ENT:Link( Target ) return false, "Refill crates cannot be linked!" end + -- Don't link if it's not the right ammo type + if Target.BulletData.Id ~= self.Id then + return false, "Wrong ammo type!" + end + -- Don't link if it's a blacklisted round type for this gun local Blacklist = ACF.AmmoBlacklist[ Target.RoundType ] or {} @@ -388,18 +423,6 @@ function ENT:Link( Target ) return false, "That round type cannot be used with this gun!" end - -- Dont't link if it's too far from this gun - if RetDist( self, Target ) > 512 * self.LinkRangeMul then - return false, "That crate is too far to be connected with this gun!" - end - - -- Don't link if it's already linked - for _, 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 ) @@ -479,54 +502,13 @@ function ENT:CanProperty( _, property ) 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 and table.HasValue(WireTable, v.Src:GetClass()) then - return self:GetUser(v.Src) - end - end - end - end - return inp.Owner or inp:CPPIGetOwner() - -end - function ENT:TriggerInput( iname, value ) if (iname == "Unload" and value > 0 and not 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:CPPIGetOwner() + self.User = ACE_GetWeaponUser( self, self.Inputs.Fire.Src ) if not IsValid(self.User) then self.User = self:CPPIGetOwner() end self:FireShell() self:Think() @@ -553,13 +535,6 @@ function ENT:TriggerInput( iname, value ) 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:Heat_Function() --print(DeltaTime) @@ -597,10 +572,8 @@ end function ENT:TrimDistantCrates() for _, Crate in pairs(self.AmmoLink) do - if IsValid( Crate ) and Crate.Load and RetDist( self, Crate ) >= 512 then - self:Unlink( Crate ) - soundstr = "physics/metal/metal_box_impact_bullet" .. tostring(math.random(1, 3)) .. ".wav" - self:EmitSound(soundstr, 500, 100) + if IsValid( Crate ) and Crate.Load and not IsInRetDist( self, Crate, AmmoLinkDistBase * self.LinkRangeMul ) then + BreakGunLink( self, Crate ) end end @@ -608,10 +581,8 @@ end function ENT:TrimDistantCrewSeats() for _, Seat in pairs(self.CrewLink) do - if IsValid( Seat ) and RetDist( self, Seat ) > 100 then - self:Unlink( Seat ) - soundstr = "physics/metal/metal_canister_impact_hard" .. tostring(math.random(1, 3)) .. ".wav" - self:EmitSound(soundstr,500,100) + if IsValid( Seat ) and not IsInRetDist( self, Seat, CrewLinkDistBase * self.LinkRangeMul ) then + BreakGunLink( self, Seat ) end end end @@ -674,16 +645,16 @@ function ENT:Think() local Time = CurTime() if self.LastSend + 1 <= Time then - local Ammo = 0 + local Ammo = 0 - for _, Crate in pairs(self.AmmoLink) do --UnlinkDistance + --UnlinkDistance + for _, Crate in pairs(self.AmmoLink) do if IsValid( Crate ) and Crate.Load and Crate.Legal then - if RetDist( self, Crate ) < 512 * self.LinkRangeMul then + + if IsInRetDist( self, Crate, AmmoLinkDistBase * self.LinkRangeMul ) then Ammo = Ammo + (Crate.Ammo or 0) else - self:Unlink( Crate ) - soundstr = "physics/metal/metal_box_impact_bullet" .. tostring(math.random(1, 3)) .. ".wav" - self:EmitSound(soundstr,500,100) + BreakGunLink( self, Crate ) end end end @@ -744,7 +715,7 @@ function ENT:ReloadMag() 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:EmitSound("weapons/357/357_reload4.wav",68,100) self.CurrentShot = 0 Wire_TriggerOutput(self, "Ready", 0) else @@ -867,7 +838,7 @@ do 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:EmitSound("weapons/357/357_reload4.wav",68,100) timer.Simple(self.LastLoadDuration, function() if IsValid(self) then self.CurrentShot = 0 end end) else self:LoadAmmo(false, false) @@ -961,7 +932,7 @@ function ENT:LoadAmmo( AddTime, Reload ) self.BulletData.PropMass = 0 self.BulletData.ProjMass = 0 - self:EmitSound("weapons/shotgun/shotgun_empty.wav",500,100) + self:EmitSound("weapons/shotgun/shotgun_empty.wav",68,100) Wire_TriggerOutput(self, "Loaded", "Empty") self.NextFire = curTime + 0.5 @@ -986,7 +957,7 @@ function ENT:UnloadAmmo() self.Ready = false Wire_TriggerOutput(self, "Ready", 0) - self:EmitSound("weapons/shotgun/shotgun_empty.wav",500,100) + self:EmitSound("weapons/shotgun/shotgun_empty.wav",68,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 diff --git a/lua/entities/acf_missile/init.lua b/lua/entities/acf_missile/init.lua index 4be4a5a5..20586986 100644 --- a/lua/entities/acf_missile/init.lua +++ b/lua/entities/acf_missile/init.lua @@ -356,8 +356,8 @@ function ENT:CalcFlight() self.FlightTime = Flight --Missile trajectory debugging - debugoverlay.Line(Pos, EndPos, 10, Color(0, 255, 0)) - debugoverlay.Line(EndPos, EndPos + Dir:GetNormalized() * 50, 10, Color(0, 0, 255)) + --.Line(Pos, EndPos, 10, Color(0, 255, 0)) + --debugoverlay.Line(EndPos, EndPos + Dir:GetNormalized() * 50, 10, Color(0, 0, 255)) self:DoFlight() end @@ -652,11 +652,9 @@ end ----- Skin/Bodygroup/effect/Sound functions --=========================================================================================== function ENT:LaunchEffect() - local sound = self.BulletData.Sound or ACF_GetGunValue(self.BulletData, "sound") - - if sound then - self:EmitSound(sound, 511, 100) - end + local Effect = EffectData() + Effect:SetEntity( self ) + util.Effect( "acf_missilelaunch", Effect, true, true ) end function ENT:UpdateSkin() diff --git a/lua/entities/acf_missileradar/init.lua b/lua/entities/acf_missileradar/init.lua index ced447b2..224e6170 100644 --- a/lua/entities/acf_missileradar/init.lua +++ b/lua/entities/acf_missileradar/init.lua @@ -113,13 +113,17 @@ function MakeACF_MissileRadar(Owner, Pos, Angle, Id) Radar:SetAngles(Angle) Radar:SetPos(Pos) - Radar.Model = radar.model - Radar.Weight = radar.weight - Radar.ACFName = radar.name - Radar.ConeDegs = radar.viewcone - Radar.Range = radar.range - Radar.Id = Id - Radar.Class = radar.class + Radar.Model = radar.model + Radar.Weight = radar.weight + Radar.ACFName = radar.name + Radar.ConeDegs = radar.viewcone + Radar.Range = radar.range + Radar.Id = Id + Radar.Class = radar.class + + Radar.Sound = ACFM.DefaultRadarSound + Radar.DefaultSound = Radar.Sound + Radar.SoundPitch = 100 Radar:Spawn() Radar:SetPlayer(Owner) @@ -132,6 +136,8 @@ function MakeACF_MissileRadar(Owner, Pos, Angle, Id) Owner:AddCleanup( "acfmenu", Radar ) Radar:SetNWString( "WireName", Radar.ACFName ) + Radar:SetNWString( "Sound", Radar.Sound ) + Radar:SetNWInt( "SoundPitch", Radar.SoundPitch ) return Radar @@ -139,9 +145,6 @@ end list.Set( "ACFCvars", "acf_missileradar", {"id"} ) duplicator.RegisterEntityClass("acf_missileradar", MakeACF_MissileRadar, "Pos", "Angle", "Id" ) - - - function ENT:CreateRadar(ACFName, ConeDegs) self.ConeDegs = ConeDegs @@ -151,9 +154,6 @@ function ENT:CreateRadar(ACFName, ConeDegs) end - - - function ENT:RefreshClientInfo() self:SetNWFloat("ConeDegs", self.ConeDegs) @@ -163,9 +163,6 @@ function ENT:RefreshClientInfo() end - - - function ENT:SetModelEasy(mdl) local Rack = self @@ -181,12 +178,8 @@ function ENT:SetModelEasy(mdl) if (phys:IsValid()) then phys:SetMass(Rack.Weight) end - end - - - function ENT:Think() if self.Inputs.Active.Value ~= 0 and self.Active and self.Legal then @@ -218,10 +211,8 @@ function ENT:Think() self:GetOverlayText() return true - end - function ENT:UpdateStatus() if self.Active then @@ -285,13 +276,19 @@ function ENT:ScanForMissiles() self.OutputData.Velocity = velArray if i > (self.LastMissileCount or 0) then - self:EmitSound( self.Sound or ACFM.DefaultRadarSound, 500, 100 ) + self:EmitRadarSound() end self.LastMissileCount = i end +function ENT:EmitRadarSound() + local Effect = EffectData() + Effect:SetEntity( self ) + util.Effect( "acf_radar_noise", Effect, true, true ) +end + function ENT:ClearOutputs() if #self.Outputs.Entities.Value > 0 then diff --git a/lua/entities/acf_rack/init.lua b/lua/entities/acf_rack/init.lua index 0b01a4a1..0a79fed9 100644 --- a/lua/entities/acf_rack/init.lua +++ b/lua/entities/acf_rack/init.lua @@ -55,12 +55,12 @@ end local RackWireDescs = { --Inputs - ["Reload"] = "Arms this rack. Its mandatory to set this since racks don't reload automatically.", - ["Delay"] = "Sets a specific delay to guidance control over the default one in seconds.\n Note that you cannot override lower values than default.", - ["TargetPos"] = "Defines the Target position for the ordnance in this rack. This only works for Wire and laser guidances.", + ["Reload"] = "Arms this rack. Its mandatory to set this since racks don't reload automatically.", + ["Delay"] = "Sets a specific delay to guidance control over the default one in seconds.\n Note that you cannot override lower values than default.", + ["TargetPos"] = "Defines the Target position for the ordnance in this rack. This only works for Wire and laser guidances.", --Outputs - ["Ready"] = "Returns if the rack is ready to fire." + ["Ready"] = "Returns if the rack is ready to fire." } @@ -68,33 +68,33 @@ function ENT:Initialize() self.BaseClass.Initialize(self) - self.SpecialHealth = false --If true needs a special ACF_Activate function - self.SpecialDamage = false --If true needs a special ACF_OnDamage function --NOTE: you can't "fix" missiles with setting this to false, it acts like a prop!!!! - self.ReloadTime = 1 - self.RackStatus = "Empty" - self.Ready = true - self.Firing = nil - self.NextFire = 1 - self.PostReloadWait = CurTime() - self.WaitFunction = self.GetFireDelay - self.NextLegalCheck = ACF.CurTime + math.random(ACF.Legal.Min, ACF.Legal.Max) -- give any spawning issues time to iron themselves out - self.Legal = true - self.LegalIssues = "" - self.LastSend = 0 + self.SpecialHealth = false --If true needs a special ACF_Activate function + self.SpecialDamage = false --If true needs a special ACF_OnDamage function --NOTE: you can't "fix" missiles with setting this to false, it acts like a prop!!!! + self.ReloadTime = 1 + self.RackStatus = "Empty" + self.Ready = true + self.Firing = nil + self.NextFire = 1 + self.PostReloadWait = CurTime() + self.WaitFunction = self.GetFireDelay + self.NextLegalCheck = ACF.CurTime + math.random(ACF.Legal.Min, ACF.Legal.Max) -- give any spawning issues time to iron themselves out + self.Legal = true + self.LegalIssues = "" + self.LastSend = 0 self:CPPISetOwner(self) - self.IsMaster = true - self.CurAmmo = 1 - self.Sequence = 1 - self.LastThink = CurTime() + self.IsMaster = true + self.CurAmmo = 1 + self.Sequence = 1 + self.LastThink = CurTime() - self.BulletData = {} - self.BulletData.Type = "Empty" - self.BulletData.PropMass = 0 - self.BulletData.ProjMass = 0 + self.BulletData = {} + self.BulletData.Type = "Empty" + self.BulletData.PropMass = 0 + self.BulletData.ProjMass = 0 - self.ForceTdelay = 0 - self.Inaccuracy = 1 + self.ForceTdelay = 0 + self.Inaccuracy = 1 self.Inputs = WireLib.CreateSpecialInputs( self, { "Fire", "Reload (" .. RackWireDescs["Reload"] .. ")", "Track Delay (" .. RackWireDescs["Delay"] .. ")", "Target Pos (" .. RackWireDescs["TargetPos"] .. ")" }, { "NORMAL", "NORMAL", "NORMAL", "VECTOR" } ) @@ -227,54 +227,11 @@ function ENT:UnloadAmmo() -- we're ok with mixed munitions. 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 not IsValid(v.Src) then return inp.Owner or inp:CPPIGetOwner() end - if table.HasValue(WireTable, v.Src:GetClass()) then - return self:GetUser(v.Src) - end - end - end - end - return inp.Owner or inp:CPPIGetOwner() - -end - function ENT:TriggerInput( iname , value ) if ( iname == "Fire" and value ~= 0 and ACF.GunfireEnabled and self.Legal ) then if self.NextFire >= 1 then - self.User = self:GetUser(self.Inputs["Fire"].Src) + self.User = ACE_GetWeaponUser( self, self.Inputs.Fire.Src ) if not IsValid(self.User) then self.User = self:CPPIGetOwner() end self:FireMissile() self:Think() @@ -440,7 +397,7 @@ function ENT:Think() self.ReloadTime = nil self:Reload() elseif self.ReloadTime and self.ReloadTime > 1 then - self:EmitSound( "acf_extra/airfx/weapon_select.wav", 500, 100 ) + self:EmitSound( "acf_extra/airfx/weapon_select.wav", 75, 100 ) self.ReloadTime = nil end elseif self.NextFire >= 1 and Ammo == 0 then @@ -571,7 +528,7 @@ end function ENT:AddMissile() - self:EmitSound( "acf_extra/tankfx/resupply_single.wav", 500, 100 ) + self:EmitSound( "acf_extra/tankfx/resupply_single.wav", 75, 100 ) self:TrimNullMissiles() @@ -604,17 +561,10 @@ function ENT:AddMissile() end local NextIdx = #self.Missiles - timer.Simple(0.02, function() - if IsValid(missile) then - local _, _, muzzle = self:GetMuzzle( NextIdx , missile ) - - debugoverlay.Cross(muzzle.Pos, 5, 10, Color(255,255,255,255), true) + local _, _, pos = self:GetMuzzle( NextIdx , missile ) - missile:SetPos(self:WorldToLocal(muzzle.Pos)) - missile:SetAngles(self:GetAngles()) - - end - end) + missile:SetPos(pos) + missile:SetAngles(self:GetAngles()) missile:SetParent(self) missile:SetParentPhysNum(0) @@ -622,6 +572,8 @@ function ENT:AddMissile() if self.HideMissile then missile:SetNoDraw(true) end if self.ProtectMissile then missile:SetNotSolid(true) end + missile:SetNWEntity( "Launcher", missile.Launcher ) + missile:Spawn() self.Missiles[NextIdx + 1] = missile @@ -671,22 +623,20 @@ function ENT:LoadAmmo() end -function MakeACF_Rack(Owner, Pos, Angle, Id, UpdateRack) +function MakeACF_Rack(Owner, Pos, Angle, Id) - if not IsValid(UpdateRack) and not Owner:CheckLimit("_acf_rack") then return false end + if not Owner:CheckLimit("_acf_rack") then return false end - local Rack = UpdateRack or ents.Create("acf_rack") + local Rack = ents.Create("acf_rack") if not IsValid(Rack) then return false end Rack:SetAngles(Angle) Rack:SetPos(Pos) + Rack:Spawn() - if not UpdateRack then --print("no update") - Rack:Spawn() - Owner:AddCount("_acf_rack", Rack) - Owner:AddCleanup( "acfmenu", Rack ) - end + Owner:AddCount("_acf_rack", Rack) + Owner:AddCleanup( "acfmenu", Rack ) if not ACE_CheckRack( Id ) then Id = "1xRK" @@ -712,42 +662,35 @@ function MakeACF_Rack(Owner, Pos, Angle, Id, UpdateRack) end -- Custom BS for karbine. Magazine Size, Mag reload Time - Rack.MagSize = 1 - if gundef["magsize"] then - Rack.MagSize = math.max(Rack.MagSize, gundef["magsize"] or 1) - end - Rack.MagReload = 0 - if gundef["magreload"] then - Rack.MagReload = math.max(Rack.MagReload, gundef["magreload"]) - end + Rack.MagSize = table.Count(gundef.mountpoints) or 1 + Rack.MagReload = gundef.magreload or 0 local gunclass = RackClasses[Rack.Class] or ErrorNoHalt("Couldn't find the " .. tostring(Rack.Class) .. " gun-class!") - Rack.Muzzleflash = gundef.muzzleflash or gunclass.muzzleflash or "" - Rack.RoFmod = gunclass["rofmod"] or 1 - Rack.Sound = gundef.sound or gunclass.sound or "" - Rack.Inaccuracy = gundef["spread"] or gunclass["spread"] or 1 + Rack.Muzzleflash = gundef.muzzleflash or gunclass.muzzleflash or "" + Rack.RoFmod = gunclass["rofmod"] or 1 + Rack.Sound = gundef.sound or gunclass.sound or "acf_extra/airfx/rocket_fire2.wav" + Rack.DefaultSound = Rack.Sound + Rack.SoundPitch = 100 + Rack.Inaccuracy = gundef["spread"] or gunclass["spread"] or 1 - Rack.HideMissile = ACF_GetRackValue(Id, "hidemissile") or false - Rack.ProtectMissile = gundef.protectmissile or gunclass.protectmissile or false - Rack.CustomArmour = gundef.armour or gunclass.armour or 1 + Rack.HideMissile = ACF_GetRackValue(Id, "hidemissile") or false + Rack.ProtectMissile = gundef.protectmissile or gunclass.protectmissile or false + Rack.CustomArmour = gundef.armour or gunclass.armour or 1 - Rack.ReloadMultiplier = ACF_GetRackValue(Id, "reloadmul") - Rack.WhitelistOnly = ACF_GetRackValue(Id, "whitelistonly") + Rack.ReloadMultiplier = ACF_GetRackValue(Id, "reloadmul") + Rack.WhitelistOnly = ACF_GetRackValue(Id, "whitelistonly") Rack:SetNWString("WireName",Rack.name) Rack:SetNWString( "Class", Rack.Class ) Rack:SetNWString( "ID", Rack.Id ) Rack:SetNWString( "Sound", Rack.Sound ) + Rack:SetNWInt( "SoundPitch", Rack.SoundPitch ) - if not UpdateRack or Rack.Model ~= Rack:GetModel() then - - Rack:SetModel( Rack.Model ) - Rack:PhysicsInit( SOLID_VPHYSICS ) - Rack:SetMoveType( MOVETYPE_VPHYSICS ) - Rack:SetSolid( SOLID_VPHYSICS ) - end - + Rack:SetModel( Rack.Model ) + Rack:PhysicsInit( SOLID_VPHYSICS ) + Rack:SetMoveType( MOVETYPE_VPHYSICS ) + Rack:SetSolid( SOLID_VPHYSICS ) local phys = Rack:GetPhysicsObject() if (phys:IsValid()) then @@ -791,9 +734,9 @@ function ENT:FireMissile() ReloadTime = self:GetFireDelay(missile) - local attach, inverted, muzzle = self:GetMuzzle(curShot - 1, missile) + local attach, inverted, pos = self:GetMuzzle(curShot - 1, missile) - local MuzzleVec = muzzle.Ang:Forward() + local MuzzleVec = self:GetAngles():Forward() local coneAng = math.tan(math.rad(self:GetInaccuracy())) local randUnitSquare = (self:GetUp() * (2 * math.random() - 1) + self:GetRight() * (2 * math.random() - 1)) @@ -815,7 +758,7 @@ function ENT:FireMissile() local bdata = missile.BulletData - bdata.Pos = muzzle.Pos + bdata.Pos = pos bdata.Flight = (self:GetAngles():Forward() + spread):GetNormalized() * (bdata.MuzzleVel or missile.MinimumSpeed or 1) * (inverted and -1 or 1) if missile.RackModelApplied then @@ -831,9 +774,10 @@ function ENT:FireMissile() if self.Sound and self.Sound ~= "" then missile.BulletData.Sound = self.Sound + missile.BulletData.Pitch = self.SoundPitch end - missile:DoFlight(bdata.Pos, ShootVec) + missile:DoFlight(pos, ShootVec) missile:Launch() self:SetLoadedWeight() @@ -844,7 +788,7 @@ function ENT:FireMissile() self:SetNWInt("Ammo", Ammo) else - self:EmitSound("weapons/pistol/pistol_empty.wav",500,100) + self:EmitSound("weapons/shotgun/shotgun_empty.wav",68,100) end self.Ready = false @@ -854,13 +798,13 @@ function ENT:FireMissile() self.ReloadTime = ReloadTime else - self:EmitSound("weapons/pistol/pistol_empty.wav",500,100) + self:EmitSound("weapons/shotgun/shotgun_empty.wav",68,100) end end function ENT:MuzzleEffect() - self:EmitSound( "phx/epicmetal_hard.wav", 500, 100 ) + self:EmitSound( "phx/epicmetal_hard.wav", 75, 100 ) end function ENT:PreEntityCopy() @@ -880,22 +824,13 @@ function ENT:PreEntityCopy() duplicator.StoreEntityModifier( self, "ACFAmmoLink", info ) end - duplicator.StoreEntityModifier( self, "ACFRackInfo", {Id = self.Id} ) - --Wire dupe info self.BaseClass.PreEntityCopy( self ) end - - - function ENT:PostEntityPaste( Player, Ent, CreatedEntities ) - self.Id = Ent.EntityMods.ACFRackInfo.Id - - MakeACF_Rack(self:CPPIGetOwner(), self:GetPos(), self:GetAngles(), self.Id, self) - if Ent.EntityMods and Ent.EntityMods.ACFAmmoLink and Ent.EntityMods.ACFAmmoLink.entities then local AmmoLink = Ent.EntityMods.ACFAmmoLink if AmmoLink.entities and next(AmmoLink.entities) then @@ -909,23 +844,11 @@ function ENT:PostEntityPaste( Player, Ent, CreatedEntities ) Ent.EntityMods.ACFAmmoLink = nil end - --Wire dupe info self.BaseClass.PostEntityPaste( self, Player, Ent, CreatedEntities ) end - - - -function ACF_Rack_OnPhysgunDrop(_, ent) - if ent:GetClass() == "acf_rack" then - timer.Simple(0.01, function() if IsValid(ent) then ent:SetLoadedWeight() end end) - end -end - -hook.Add("PhysgunDrop", "ACF_Rack_OnPhysgunDrop", ACF_Rack_OnPhysgunDrop) - function ENT:OnRemove() Wire_Remove(self) end diff --git a/lua/entities/acf_rack/shared.lua b/lua/entities/acf_rack/shared.lua index e10b11db..f364aa51 100644 --- a/lua/entities/acf_rack/shared.lua +++ b/lua/entities/acf_rack/shared.lua @@ -2,65 +2,60 @@ DEFINE_BASECLASS("base_wire_entity") -ENT.Type = "anim" -ENT.Base = "base_wire_entity" -ENT.PrintName = "ACF Missile Rack" +ENT.Type = "anim" +ENT.Base = "base_wire_entity" +ENT.PrintName = "ACF Missile Rack" -ENT.Spawnable = false -ENT.AdminOnly = false -ENT.AdminSpawnable = false +ENT.Spawnable = false +ENT.AdminOnly = false +ENT.AdminSpawnable = false +local Weapons = ACF.Weapons.Guns +local Racks = ACF.Weapons.Racks -function ENT:GetMunitionAngPos(missile, attach, attachname) +local function VerifyMountData(mountpoint) - local angpos + mountpoint.pos = mountpoint.pos or vector_origin + mountpoint.offset = mountpoint.offset or vector_origin + mountpoint.scaledir = mountpoint.scaledir or vector_origin - if attach ~= 0 then - angpos = self:GetAttachment(attach) - else - angpos = {Pos = self:GetPos(), Ang = self:GetAngles()} - end + return mountpoint +end - local guns = list.Get("ACFEnts").Guns - local gun = guns[missile.BulletData.Id] +function ENT:GetMunitionAngPos(missile, _, attachname) - if not gun then return angpos end + local GunData = Weapons[missile.BulletData.Id] + local RackData = Racks[self.Id] - local offset = (gun.modeldiameter or gun.caliber) / (2.54 * 2) - local rack = ACF.Weapons.Racks[self.Id] + if GunData and RackData then - if not rack then return angpos end + local offset = (GunData.modeldiameter or GunData.caliber) / (2.54 * 2) - mountpoint = rack.mountpoints[attachname] or {["offset"] = Vector(0,0,0), ["scaledir"] = Vector(0, 0, -1)} - inverted = rack.inverted or false + local mountpoint = VerifyMountData(RackData.mountpoints[attachname]) + local inverted = RackData.inverted or false + local pos = self:LocalToWorld(mountpoint.pos + mountpoint.offset + mountpoint.scaledir * offset) - if mountpoint.pos then - angpos.Pos = mountpoint.pos - end + debugoverlay.Cross(pos, 5, 5, Color(0,255,0,255), true) - angpos.Pos = self:LocalToWorld(angpos.Pos + mountpoint.offset + mountpoint.scaledir * offset) - - return inverted, angpos + return inverted, pos + end end function ENT:GetMuzzle(shot, missile) shot = (shot or 0) + 1 local attachname = "missile" .. shot - local attach = self:LookupAttachment(attachname) - local inverted, angpos = self:GetMunitionAngPos(missile, attach, attachname) - if attach ~= 0 then return attach, inverted, angpos end + local inverted, pos = self:GetMunitionAngPos(missile, attach, attachname) + if attach ~= 0 then return attach, inverted, pos end attachname = "missile1" - local attach = self:LookupAttachment(attachname) - local inverted, angpos = self:GetMunitionAngPos(missile, attach, attachname) - if attach ~= 0 then return attach, inverted, angpos end + local inverted, pos = self:GetMunitionAngPos(missile, attach, attachname) + if attach ~= 0 then return attach, inverted, pos end attachname = "muzzle" - local attach = self:LookupAttachment(attachname) - local inverted, angpos = self:GetMunitionAngPos(missile, attach, attachname) - if attach ~= 0 then return attach, inverted, angpos end + local inverted, pos = self:GetMunitionAngPos(missile, attach, attachname) + if attach ~= 0 then return attach, inverted, pos end - return 0, false, {Pos = self:GetPos(), Ang = self:GetAngles()} + return 0, false, pos end diff --git a/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua b/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua index 4478d116..80cbf78f 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua @@ -47,11 +47,6 @@ local function isRadar(ent) return radarTypes[ent:GetClass()] 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 @@ -215,18 +210,18 @@ e2function string entity:acfName() if isGearbox(this) then acftype = "Mobility" end if isGun(this) then acftype = "Guns" end if (acftype == "") then return "" end - local List = list.Get("ACFEnts") + local List = ACF.Weapons 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") + local List = ACF.Weapons return List["Mobility"][this.Id]["category"] or "" end if isGun(this) then - local Classes = list.Get("ACFClasses") + local Classes = ACF.Classes return Classes["GunClass"][this.Class]["name"] or "" end if isAmmo(this) then return this.RoundType or "" end @@ -282,6 +277,33 @@ e2function number acfDragDiv() return ACF.DragDiv end +--returns heat of acf entity +e2function number entity:acfHeat() + if IsValid(this) then + local Heat + if isGun(this) then + Heat = ACE_HeatFromGun(this, this.Heat, this.DeltaTime) + elseif isEngine(this) then + Heat = ACE_HeatFromEngine(this) + else + Heat = ACE.AmbientTemp + end + return Heat + end + return 0 -- Return a default value if the entity is not valid +end + +--returns latest ACE version +e2function number acfVersion() + return ACF.CurrentVersion +end + +--returns current ACE version +e2function number acfCurVersion() + return ACF.Version +end + + -- [ Engine Functions ] -- @@ -621,15 +643,28 @@ 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) + if restrictInfo(self, this) or not isGun(this) or not this.ReloadTime then return 0 end + return this.ReloadTime 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 ) + if restrictInfo(self, this) or not isGun(this) then return 1 end + if this.BulletData.Type == "Empty" then return 0 end + + local reloadTime + if this.MagSize == 1 then + reloadTime = this.ReloadTime + else + if this.MagSize - this.CurrentShot > 0 then + reloadTime = this.ReloadTime + else + reloadTime = this.MagReload + this.ReloadTime + end + end + + return math.Clamp( 1 - (this.NextFire - CurTime()) / reloadTime, 0, 1 ) end __e2setcost( 1 ) @@ -868,6 +903,20 @@ e2function number entity:acfBlastRadius() return 0 end +--[[ Returns a table of all crew seats linked to the entity - no idea why not worky +e2function table entity:acfGetCrew() + local Crew = {} + local Has_Crew = #this.CrewLink > 0 + + if IsValid(this) and not restrictInfo(this) and Has_Crew then + Crew = this.CrewLink + end + + return Crew +end +]]-- + + -- [ Armor Functions ] -- @@ -949,7 +998,7 @@ e2function table entity:acfPropArmorData() local mat = this.ACF.Material if not mat then return ret end - local matData = ACE.Armors[mat] + local matData = ACE.ArmorTypes[mat] if not matData then return ret end ret.size = 4 diff --git a/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua b/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua index fc3006e8..9d4157a0 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua @@ -17,6 +17,10 @@ E2Helper.Descriptions["acfInfoRestricted"] = "Returns 1 if functions returning s 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" +E2Helper.Descriptions["acfHeat"] = "Returns heat of an ACF entity" +E2Helper.Descriptions["acfVersion"] = "Returns latest git version of acf" +E2Helper.Descriptions["acfCurVersion"] = "Returns current version of acf" +--E2Helper.Descriptions["acfGetCrew"] = "Returns table of crew seats, linked to entity" --engine E2Helper.Descriptions["acfMaxTorque"] = "Returns the maximum torque (in N/m) of an ACF engine." diff --git a/lua/starfall/libs_sv/acf.lua b/lua/starfall/libs_sv/acf.lua index 0442436b..15b378b2 100644 --- a/lua/starfall/libs_sv/acf.lua +++ b/lua/starfall/libs_sv/acf.lua @@ -75,11 +75,6 @@ local function isRadar(ent) return radarTypes[ent:GetClass()] 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 ) @@ -486,7 +481,7 @@ end -- Set ammo properties local ammo_properties = {} -for id, data in pairs(list.Get("ACFRoundTypes")) do +for id, data in pairs(ACF.RoundTypes) do ammo_properties[id] = { name = data.name, desc = data.desc, @@ -815,6 +810,24 @@ function acf_library.getAllAmmoBoxes() return ammoBoxes end +--- Returns latest version of acf +-- @server +-- @return number +function acf_library.getVersion() + local version = ACF.CurrentVersion + + return version +end + +--- Returns server version of acf +-- @server +-- @return number +function acf_library.getCurrentVersion() + local version = ACF.Version + + return version +end + ---------------------------------------- -- Entity Methods @@ -997,7 +1010,7 @@ function ents_methods:acfName () if isGearbox( this ) then acftype = "Mobility" end if isGun( this ) then acftype = "Guns" end if ( acftype == "" ) then return "" end - local List = list.Get( "ACFEnts" ) + local List = ACF.Weapons return List[ acftype ][ this.Id ][ "name" ] or "" end @@ -1011,11 +1024,11 @@ function ents_methods:acfType () if not ( this and this:IsValid() ) then SF.Throw( "Entity is not valid", 2 ) end if isEngine( this ) or isGearbox( this ) then - local List = list.Get( "ACFEnts" ) + local List = ACF.Weapons return List[ "Mobility" ][ this.Id ][ "category" ] or "" end if isGun( this ) then - local Classes = list.Get( "ACFClasses" ) + local Classes = ACF.Classes return Classes[ "GunClass" ][ this.Class ][ "name" ] or "" end if isAmmo( this ) then return this.RoundType or "" end @@ -1968,8 +1981,8 @@ function ents_methods:acfReloadTime () if not ( this and this:IsValid() ) then SF.Throw( "Entity is not valid", 2 ) end - if restrictInfo( this ) or not isGun( this ) or this.Ready then return 0 end - return reloadTime( this ) + if restrictInfo( this ) or not isGun( this ) or not this.ReloadTime then return 0 end + return this.ReloadTime end --- Returns number between 0 and 1 which represents reloading progress of an ACF weapon. Useful for progress bars @@ -1981,8 +1994,20 @@ function ents_methods:acfReloadProgress () if not ( this and this:IsValid() ) then SF.Throw( "Entity is not valid", 2 ) end - 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 ) + if restrictInfo( this ) or not isGun( this ) then return 1 end + + local reloadTime + if this.MagSize == 1 then + reloadTime = this.ReloadTime + else + if this.MagSize - this.CurrentShot > 0 then + reloadTime = this.ReloadTime + else + reloadTime = this.MagReload + this.ReloadTime + end + end + + return math.Clamp( 1 - (this.NextFire - CurTime()) / reloadTime, 0, 1 ) end --- Returns time it takes for an ACF weapon to reload magazine @@ -1994,7 +2019,7 @@ function ents_methods:acfMagReloadTime () if not ( this and this:IsValid() ) then SF.Throw( "Entity is not valid", 2 ) end - if restrictInfo( instance.player , this ) or not isGun( this ) or not this.MagReload then return 0 end + if restrictInfo( this ) or not isGun( this ) or not this.MagReload then return 0 end return this.MagReload end @@ -2220,6 +2245,51 @@ function ents_methods:acfDragCoef() return ( this.BulletData[ "DragCoef" ] or 0 ) / ACF.DragDiv end +--- Returns the heat of an ACF entity +-- @server +-- @return number The heat value of the entity +function ents_methods:acfHeat() + checktype(self, ents_metatable) + local this = unwrap(self) + + if not (this and this:IsValid()) then + SF.Throw("Entity is not valid", 2) + end + + local Heat + if isGun(this) then + Heat = ACE_HeatFromGun(this, this.Heat, this.DeltaTime) + elseif isEngine(this) then + Heat = ACE_HeatFromEngine(this) + else + Heat = ACE.AmbientTemp + end + + return Heat +end + +--- Returns all crewseats linked to an acf entity +-- @server +-- @return table crewseats entities +function ents_methods:acfGetCrew() + checktype(self, ents_metatable) + local this = unwrap(self) + + if not (this and this:IsValid()) then + SF.Throw("Entity is not valid", 2) + end + + if restrictInfo( this ) then + return {} + end + + local Crew = table.Copy(this.CrewLink) + + return Crew +end + + + -- [ Armor Functions ] -- --- Returns the current health of an entity @@ -2314,7 +2384,7 @@ function ents_methods:acfPropArmorData() local mat = this.ACF.Material if not mat then return empty end - local matData = ACE.Armors[mat] + local matData = ACE.ArmorTypes[mat] if not matData then return empty end return { diff --git a/lua/weapons/gmod_tool/stools/acfarmorprop.lua b/lua/weapons/gmod_tool/stools/acfarmorprop.lua index 76ee88bb..8f8ef94a 100644 --- a/lua/weapons/gmod_tool/stools/acfarmorprop.lua +++ b/lua/weapons/gmod_tool/stools/acfarmorprop.lua @@ -94,7 +94,7 @@ if CLIENT then -- Material ComboBox creation local function MaterialTable( panel ) - local MaterialTypes = ACE.Armors + local MaterialTypes = ACE.ArmorTypes if not MaterialTypes then return end local Material = GetConVar("acfarmorprop_material"):GetString() diff --git a/lua/weapons/gmod_tool/stools/acfsound.lua b/lua/weapons/gmod_tool/stools/acfsound.lua index 2a3da5be..79c76ba1 100644 --- a/lua/weapons/gmod_tool/stools/acfsound.lua +++ b/lua/weapons/gmod_tool/stools/acfsound.lua @@ -44,11 +44,13 @@ ACF.SoundToolSupport = { acf_gun = { - GetSound = function(ent) return { Sound = ent.Sound } end, + GetSound = function(ent) return { Sound = ent.Sound, Pitch = ent.SoundPitch or 100 } end, SetSound = function(ent, soundData) ent.Sound = soundData.Sound + ent.SoundPitch = soundData.Pitch ent:SetNWString( "Sound", soundData.Sound ) + ent:SetNWInt( "SoundPitch", soundData.Pitch ) end, ResetSound = function(ent) @@ -58,16 +60,19 @@ ACF.SoundToolSupport = { local sound = lookup.sound or GunClasses[Class]["sound"] - local soundData = { Sound = sound } + local soundData = { Sound = sound, Pitch = 100 } local setSound = ACF.SoundToolSupport["acf_gun"].SetSound setSound( ent, soundData ) + end, + + NewFormat = function() end }, acf_engine = { - GetSound = function(ent) return { Sound = ent.SoundPath, Pitch = ent.SoundPitch } end, + GetSound = function(ent) return { Sound = ent.SoundPath, Pitch = ent.SoundPitch or 100 } end, SetSound = function(ent, soundData) ent.SoundPath = soundData.Sound @@ -89,11 +94,14 @@ ACF.SoundToolSupport = { acf_rack = { - GetSound = function(ent) return { Sound = ent.Sound } end, + GetSound = function(ent) return { Sound = ent.Sound, Pitch = ent.SoundPitch or 100 } end, SetSound = function(ent, soundData) + ent.Sound = soundData.Sound + ent.SoundPitch = soundData.Pitch ent:SetNWString( "Sound", soundData.Sound ) + ent:SetNWInt( "SoundPitch", soundData.Pitch ) end, ResetSound = function(ent) @@ -101,59 +109,76 @@ ACF.SoundToolSupport = { local Class = ent.Class local sound = GunClasses[Class]["sound"] or "" - local soundData = { Sound = sound } + local soundData = { Sound = sound, Pitch = 100 } - local setSound = ACF.SoundToolSupport["acf_gun"].SetSound + local setSound = ACF.SoundToolSupport["acf_rack"].SetSound setSound( ent, soundData ) + end, + + NewFormat = function() end + }, acf_missileradar = { - GetSound = function(ent) return { Sound = ent.Sound } end, + GetSound = function(ent) return { Sound = ent.Sound or ACFM.DefaultRadarSound, Pitch = ent.SoundPitch or 100 } end, SetSound = function(ent, soundData) ent.Sound = soundData.Sound + ent.SoundPitch = soundData.Pitch ent:SetNWString( "Sound", soundData.Sound ) + ent:SetNWInt( "SoundPitch", soundData.Pitch ) end, ResetSound = function(ent) - local soundData = {Sound = ACFM.DefaultRadarSound} + local soundData = {Sound = ACFM.DefaultRadarSound, Pitch = 100} - local setSound = ACF.SoundToolSupport["acf_gun"].SetSound + local setSound = ACF.SoundToolSupport["acf_missileradar"].SetSound setSound( ent, soundData ) end - } + }, + + NewFormat = function() + end + } local function ReplaceSound( _ , Entity , data) if not IsValid( Entity ) then return end local sound = data[1] - local pitch = data[2] or 1 + local pitch = tonumber(data[2]) or 100 + local isNew = data[3] - timer.Simple(1, function() - if not IsValid( Entity ) then return end --Caused by insta removal of the dupe + if pitch < 10 then + pitch = pitch * 100 + end - local class = Entity:GetClass() - local support = ACF.SoundToolSupport[class] + local class = Entity:GetClass() + local support = ACF.SoundToolSupport[class] - if not support then return end + if support then - support.SetSound(Entity, {Sound = sound, Pitch = pitch}) - end) + -- Before to the implementation, sounds were still being granted with the pitch you had on the slider, + -- making that the official integration makes it to use it, altering the supposed non pitch it had before + -- This should fix it, making sure to tag it with a new format in future applications. + if support.NewFormat and not isNew then + pitch = 100 + end - duplicator.StoreEntityModifier( Entity, "acf_replacesound", {sound, pitch} ) + local newdata = {sound, pitch, true} + support.SetSound(Entity, {Sound = sound, Pitch = pitch}) + duplicator.StoreEntityModifier( Entity, "acf_replacesound", newdata ) + end end duplicator.RegisterEntityModifier( "acf_replacesound", ReplaceSound ) - local function IsReallyValid(trace, ply) 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 @@ -176,7 +201,7 @@ function TOOL:LeftClick( trace ) local sound = self:GetOwner():GetInfo("wire_soundemitter_sound") local pitch = self:GetOwner():GetInfo("acfsound_pitch") - ReplaceSound( self:GetOwner(), trace.Entity, {sound, pitch} ) + ReplaceSound( self:GetOwner(), trace.Entity, {sound, pitch, true} ) return true end @@ -302,28 +327,8 @@ if CLIENT then end panel:AddItem(ClearButton) - --panel:ControlHelp( "string help" ) - - 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(ACFTranslation.SoundToolText[6]) - SoundPitch:SetConVar( "acfsound_pitch" ) - SoundPitch:SetValue( 1 ) - panel:AddItem(SoundPitch) - --]] - + panel:NumSlider( "Pitch", "acfsound_pitch", 10, 255, 0 ) + panel:ControlHelp( "Adjust the pitch of the sound. Currently supports engines, guns, racks and missile radars. \n\nNote: This will not work with dynamic sounds atm." ) end --[[ diff --git a/lua/weapons/weapon_ace_ak47/shared.lua b/lua/weapons/weapon_ace_ak47/shared.lua index 282fa068..ab9fe2e0 100644 --- a/lua/weapons/weapon_ace_ak47/shared.lua +++ b/lua/weapons/weapon_ace_ak47/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/ak47_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_amr/shared.lua b/lua/weapons/weapon_ace_amr/shared.lua index ba356f4b..31dac2a3 100644 --- a/lua/weapons/weapon_ace_amr/shared.lua +++ b/lua/weapons/weapon_ace_amr/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/amr_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_antipersonmine/init.lua b/lua/weapons/weapon_ace_antipersonmine/init.lua index b621d100..ee78550a 100644 --- a/lua/weapons/weapon_ace_antipersonmine/init.lua +++ b/lua/weapons/weapon_ace_antipersonmine/init.lua @@ -8,13 +8,13 @@ SWEP.DeployDelay = 6 --No more rocket 2 taps or sprinting lawnchairs function SWEP:DoAmmoStatDisplay() - local sendInfo = string.format( "Anti Personel Mine") + local sendInfo = string.format( "Anti Personnel Mine") sendInfo = sendInfo .. string.format(", %.1fm blast", 2 ^ 0.33 * 8) --4 taken from mine entity - self:GetOwner():SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 10)", sendInfo)) + ACE_SendNotification(self:GetOwner(), sendInfo, 10) end function SWEP:Equip() diff --git a/lua/weapons/weapon_ace_antipersonmine/shared.lua b/lua/weapons/weapon_ace_antipersonmine/shared.lua index fcac4c35..9407da17 100644 --- a/lua/weapons/weapon_ace_antipersonmine/shared.lua +++ b/lua/weapons/weapon_ace_antipersonmine/shared.lua @@ -40,10 +40,6 @@ SWEP.Primary.DefaultClip = 8 SWEP.Primary.Automatic = 0 SWEP.Primary.Ammo = "Grenade" -SWEP.Secondary.Ammo = "none" -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSoundEnabled = 1 SWEP.AimOffset = Vector(0, 0, 0) @@ -66,8 +62,6 @@ SWEP.ZoomRecoilImprovement = 0.2 -- 0.3 means 0.7 the recoil movement SWEP.CrouchAccuracyImprovement = 0.4 -- 0.3 means 0.7 the inaccuracy SWEP.CrouchRecoilImprovement = 0.2 -- 0.3 means 0.7 the recoil movement --- - function SWEP:PrimaryAttack() if not self:CanPrimaryAttack() then return end if (self:Ammo1() == 0) and (self:Clip1() == 0) then return end @@ -78,47 +72,31 @@ function SWEP:PrimaryAttack() return end - local owner = self:GetOwner() + local Owner = self:GetOwner() self.BulletData.Owner = owner self.BulletData.Gun = self - self.InaccuracyAccumulation = math.Clamp(self.InaccuracyAccumulation + self.InaccuracyAccumulationRate - self.InaccuracyDecayRate * (CurTime() - self.lastFire), 1, self.MaxInaccuracyMult) - - if not owner:HasGodMode() then - local ent = ents.Create( "ace_antipersonelmine" ) + if not Owner:HasGodMode() then - if ( IsValid( ent ) ) then + local Forward = Owner:EyeAngles():Forward() + local Pos = Owner:GetShootPos() + Forward * 32 + local Angle = Owner:EyeAngles() - local Forward = owner:EyeAngles():Forward() + ACE_CreateMine( "APL", Pos, Angle, Owner ) - ent:SetPos( owner:GetShootPos() + Forward * 32 ) - ent:SetAngles( owner:EyeAngles() ) - ent:Spawn() - ent:SetVelocity( Forward * 10 ) - owner:AddCleanup( "aceexplosives", ent ) - - if CPPI then - ent:CPPISetOwner(Entity(0)) - end - ent.DamageOwner = owner -- Done to avoid owners from manipulating the entity, but allowing the damage to be credited by him. - end end self.lastFire = CurTime() --- print("Inaccuracy: " .. self.InaccuracyAccumulation) - self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) - owner:SetAnimation( PLAYER_ATTACK1 ) + Owner:SetAnimation( PLAYER_ATTACK1 ) if self:Ammo1() > 0 then - owner:RemoveAmmo( 1, "Grenade") + Owner:RemoveAmmo( 1, "Grenade") else self:TakePrimaryAmmo(1) end --- self:TakePrimaryAmmo(1) - end function SWEP:SecondaryAttack() diff --git a/lua/weapons/weapon_ace_antitankmine/init.lua b/lua/weapons/weapon_ace_antitankmine/init.lua index 4d77f5d6..ff580516 100644 --- a/lua/weapons/weapon_ace_antitankmine/init.lua +++ b/lua/weapons/weapon_ace_antitankmine/init.lua @@ -11,7 +11,7 @@ function SWEP:DoAmmoStatDisplay() local sendInfo = string.format( "AT Mine") sendInfo = sendInfo .. string.format(", %.1fm blast", 60 ^ 0.33 * 8) --4 taken from mine entity - self:GetOwner():SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 10)", sendInfo)) + ACE_SendNotification(self:GetOwner(), sendInfo, 10) end function SWEP:Equip() diff --git a/lua/weapons/weapon_ace_antitankmine/shared.lua b/lua/weapons/weapon_ace_antitankmine/shared.lua index 77772c9d..5570d111 100644 --- a/lua/weapons/weapon_ace_antitankmine/shared.lua +++ b/lua/weapons/weapon_ace_antitankmine/shared.lua @@ -40,10 +40,6 @@ SWEP.Primary.DefaultClip = 4 SWEP.Primary.Automatic = 0 SWEP.Primary.Ammo = "Grenade" -SWEP.Secondary.Ammo = "none" -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSoundEnabled = 1 SWEP.AimOffset = Vector(0, 0, 0) @@ -76,38 +72,28 @@ function SWEP:PrimaryAttack() return end - local owner = self:GetOwner() + local Owner = self:GetOwner() - self.BulletData.Owner = owner + self.BulletData.Owner = Owner self.BulletData.Gun = self - if not owner:HasGodMode() then - local ent = ents.Create( "ace_antitankmine" ) - - if ( IsValid( ent ) ) then + if not Owner:HasGodMode() then - local Forward = owner:EyeAngles():Forward() + local Forward = Owner:EyeAngles():Forward() + local Pos = Owner:GetShootPos() + Forward * 32 + local Angle = Owner:EyeAngles() - ent:SetPos( owner:GetShootPos() + Forward * 32 ) - ent:SetAngles( owner:EyeAngles() ) - ent:Spawn() - ent:SetVelocity( Forward * 10 ) - owner:AddCleanup( "aceexplosives", ent ) + ACE_CreateMine( "ATL", Pos, Angle, Owner ) - if CPPI then - ent:CPPISetOwner( Entity(0) ) - end - ent.DamageOwner = owner -- Done to avoid owners from manipulating the entity, but allowing the damage to be credited by him. - end end self.lastFire = CurTime() self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) - owner:SetAnimation( PLAYER_ATTACK1 ) + Owner:SetAnimation( PLAYER_ATTACK1 ) if self:Ammo1() > 0 then - owner:RemoveAmmo( 1, "Grenade") + Owner:RemoveAmmo( 1, "Grenade") else self:TakePrimaryAmmo(1) end diff --git a/lua/weapons/weapon_ace_at4/shared.lua b/lua/weapons/weapon_ace_at4/shared.lua index 12d15e9f..023e83d8 100644 --- a/lua/weapons/weapon_ace_at4/shared.lua +++ b/lua/weapons/weapon_ace_at4/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/at4_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_at4t/shared.lua b/lua/weapons/weapon_ace_at4t/shared.lua index 3efb8146..71856b3e 100644 --- a/lua/weapons/weapon_ace_at4t/shared.lua +++ b/lua/weapons/weapon_ace_at4t/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/at4p_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_aug/shared.lua b/lua/weapons/weapon_ace_aug/shared.lua index f4a08fa0..1ab98949 100644 --- a/lua/weapons/weapon_ace_aug/shared.lua +++ b/lua/weapons/weapon_ace_aug/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/aug_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_awp/shared.lua b/lua/weapons/weapon_ace_awp/shared.lua index 57abb93b..1c4133c6 100644 --- a/lua/weapons/weapon_ace_awp/shared.lua +++ b/lua/weapons/weapon_ace_awp/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/awp_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_base/init.lua b/lua/weapons/weapon_ace_base/init.lua index 52d0b24c..c73e31b0 100644 --- a/lua/weapons/weapon_ace_base/init.lua +++ b/lua/weapons/weapon_ace_base/init.lua @@ -102,7 +102,7 @@ function SWEP:DoAmmoStatDisplay() sendInfo = sendInfo .. string.format(", (2)%.1fmm pen", MaxPen) end - self:GetOwner():SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 10)", sendInfo)) + ACE_SendNotification(self:GetOwner(), sendInfo, 10) end function SWEP:Equip() diff --git a/lua/weapons/weapon_ace_base/shared.lua b/lua/weapons/weapon_ace_base/shared.lua index 4f8b9deb..3e2594c6 100644 --- a/lua/weapons/weapon_ace_base/shared.lua +++ b/lua/weapons/weapon_ace_base/shared.lua @@ -18,6 +18,7 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/ak47_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns +SWEP.Secondary.Ammo = "none" SWEP.Secondary.ClipSize = -1 SWEP.Secondary.DefaultClip = -1 @@ -243,7 +244,7 @@ function SWEP:PrimaryAttack() self.Reloading = false end - local sounds = list.Get("ACESounds").GunFire[self.Primary.Sound] + local sounds = ACE.GSounds.GunFire[self.Primary.Sound] if game.SinglePlayer() then self:CallOnClient("PrimaryAttack") diff --git a/lua/weapons/weapon_ace_boundingmine/init.lua b/lua/weapons/weapon_ace_boundingmine/init.lua index 241d8f65..faa2abe5 100644 --- a/lua/weapons/weapon_ace_boundingmine/init.lua +++ b/lua/weapons/weapon_ace_boundingmine/init.lua @@ -14,7 +14,7 @@ function SWEP:DoAmmoStatDisplay() - self:GetOwner():SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 10)", sendInfo)) + ACE_SendNotification(self:GetOwner(), sendInfo, 10) end function SWEP:Equip() diff --git a/lua/weapons/weapon_ace_boundingmine/shared.lua b/lua/weapons/weapon_ace_boundingmine/shared.lua index 5e6d57fa..ce82df07 100644 --- a/lua/weapons/weapon_ace_boundingmine/shared.lua +++ b/lua/weapons/weapon_ace_boundingmine/shared.lua @@ -40,10 +40,6 @@ SWEP.Primary.DefaultClip = 3 SWEP.Primary.Automatic = 0 SWEP.Primary.Ammo = "Grenade" -SWEP.Secondary.Ammo = "none" -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSoundEnabled = 1 SWEP.AimOffset = Vector(0, 0, 0) @@ -76,37 +72,28 @@ function SWEP:PrimaryAttack() return end - local owner = self:GetOwner() + local Owner = self:GetOwner() - self.BulletData.Owner = owner + self.BulletData.Owner = Owner self.BulletData.Gun = self - if not owner:HasGodMode() then - local ent = ents.Create( "ace_boundingmine" ) - - if ( IsValid( ent ) ) then + if not Owner:HasGodMode() then - local Forward = owner:EyeAngles():Forward() + local Forward = Owner:EyeAngles():Forward() + local Pos = Owner:GetShootPos() + Forward * 32 + local Angle = Owner:EyeAngles() - ent:SetPos( owner:GetShootPos() + Forward * 32 ) - ent:SetAngles( owner:EyeAngles() ) - ent:Spawn() - ent:SetVelocity( Forward * 10 ) - owner:AddCleanup( "aceexplosives", ent ) + ACE_CreateMine( "Bounding-APL", Pos, Angle, Owner ) - if CPPI then - ent:CPPISetOwner( Entity(0) ) - end - ent.DamageOwner = owner -- Done to avoid owners from manipulating the entity, but allowing the damage to be credited by him. - end end + self.lastFire = CurTime() self:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) - owner:SetAnimation( PLAYER_ATTACK1 ) + Owner:SetAnimation( PLAYER_ATTACK1 ) if self:Ammo1() > 0 then - owner:RemoveAmmo( 1, "Grenade") + Owner:RemoveAmmo( 1, "Grenade") else self:TakePrimaryAmmo(1) end diff --git a/lua/weapons/weapon_ace_deagle/shared.lua b/lua/weapons/weapon_ace_deagle/shared.lua index ea12e9af..d8b2a2b9 100644 --- a/lua/weapons/weapon_ace_deagle/shared.lua +++ b/lua/weapons/weapon_ace_deagle/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/deagle_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_elite/shared.lua b/lua/weapons/weapon_ace_elite/shared.lua index 2edfea89..59774fa1 100644 --- a/lua/weapons/weapon_ace_elite/shared.lua +++ b/lua/weapons/weapon_ace_elite/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/elite_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_famas/shared.lua b/lua/weapons/weapon_ace_famas/shared.lua index 96d8a824..fb8d257e 100644 --- a/lua/weapons/weapon_ace_famas/shared.lua +++ b/lua/weapons/weapon_ace_famas/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/famas_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_fiveseven/shared.lua b/lua/weapons/weapon_ace_fiveseven/shared.lua index f780d72f..6c725f27 100644 --- a/lua/weapons/weapon_ace_fiveseven/shared.lua +++ b/lua/weapons/weapon_ace_fiveseven/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/fiveseven_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_galil/shared.lua b/lua/weapons/weapon_ace_galil/shared.lua index 193af7b9..005c4363 100644 --- a/lua/weapons/weapon_ace_galil/shared.lua +++ b/lua/weapons/weapon_ace_galil/shared.lua @@ -19,12 +19,8 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/galil_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound - SWEP.ZoomFOV = 60 SWEP.HasScope = false --True if the weapon has a sniper-style scope diff --git a/lua/weapons/weapon_ace_glock/shared.lua b/lua/weapons/weapon_ace_glock/shared.lua index 9d68a661..d54d9744 100644 --- a/lua/weapons/weapon_ace_glock/shared.lua +++ b/lua/weapons/weapon_ace_glock/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/glock_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound @@ -119,9 +116,9 @@ function SWEP:SecondaryAttack() if CLIENT then return end if self.Primary.Automatic then - owner:SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 2)", "<>")) + ACE_SendNotification(owner, "<>", 2) else - owner:SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 2)", "<>")) + ACE_SendNotification(owner, "<>", 2) end end diff --git a/lua/weapons/weapon_ace_grenade/init.lua b/lua/weapons/weapon_ace_grenade/init.lua index f823a75f..7d69180e 100644 --- a/lua/weapons/weapon_ace_grenade/init.lua +++ b/lua/weapons/weapon_ace_grenade/init.lua @@ -14,7 +14,7 @@ function SWEP:DoAmmoStatDisplay() - self:GetOwner():SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 10)", sendInfo)) + ACE_SendNotification(self:GetOwner(), sendInfo, 10) end function SWEP:Equip() diff --git a/lua/weapons/weapon_ace_grenade/shared.lua b/lua/weapons/weapon_ace_grenade/shared.lua index 6213a581..95671cdf 100644 --- a/lua/weapons/weapon_ace_grenade/shared.lua +++ b/lua/weapons/weapon_ace_grenade/shared.lua @@ -35,10 +35,6 @@ SWEP.Primary.DefaultClip = 5 SWEP.Primary.Automatic = false SWEP.Primary.Ammo = "Grenade" -SWEP.Secondary.Ammo = "none" -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.JustDeployed = true function SWEP:Deploy() diff --git a/lua/weapons/weapon_ace_m16/shared.lua b/lua/weapons/weapon_ace_m16/shared.lua index 129b372d..d56f38fd 100644 --- a/lua/weapons/weapon_ace_m16/shared.lua +++ b/lua/weapons/weapon_ace_m16/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/m16_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_m249saw/shared.lua b/lua/weapons/weapon_ace_m249saw/shared.lua index b25e1dee..84f57314 100644 --- a/lua/weapons/weapon_ace_m249saw/shared.lua +++ b/lua/weapons/weapon_ace_m249saw/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/m249saw_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_m3super90/shared.lua b/lua/weapons/weapon_ace_m3super90/shared.lua index d515a06c..175c5478 100644 --- a/lua/weapons/weapon_ace_m3super90/shared.lua +++ b/lua/weapons/weapon_ace_m3super90/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/m3super90_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 10 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_mac10/shared.lua b/lua/weapons/weapon_ace_mac10/shared.lua index 998e94f6..6334335c 100644 --- a/lua/weapons/weapon_ace_mac10/shared.lua +++ b/lua/weapons/weapon_ace_mac10/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/mac10_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_mp5/shared.lua b/lua/weapons/weapon_ace_mp5/shared.lua index 423d385e..eee1c6bd 100644 --- a/lua/weapons/weapon_ace_mp5/shared.lua +++ b/lua/weapons/weapon_ace_mp5/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/mp5_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_p228/shared.lua b/lua/weapons/weapon_ace_p228/shared.lua index b8fd1724..f2bdd8aa 100644 --- a/lua/weapons/weapon_ace_p228/shared.lua +++ b/lua/weapons/weapon_ace_p228/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/p228_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_p90/shared.lua b/lua/weapons/weapon_ace_p90/shared.lua index b13a2dd9..d5a78c58 100644 --- a/lua/weapons/weapon_ace_p90/shared.lua +++ b/lua/weapons/weapon_ace_p90/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/p90_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_scout/shared.lua b/lua/weapons/weapon_ace_scout/shared.lua index 7c1790e9..f3eb4bf8 100644 --- a/lua/weapons/weapon_ace_scout/shared.lua +++ b/lua/weapons/weapon_ace_scout/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/scout_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_sg552/shared.lua b/lua/weapons/weapon_ace_sg552/shared.lua index 72680cc3..47e356af 100644 --- a/lua/weapons/weapon_ace_sg552/shared.lua +++ b/lua/weapons/weapon_ace_sg552/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/sg552_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_slam/init.lua b/lua/weapons/weapon_ace_slam/init.lua index d5f12208..7ffa9690 100644 --- a/lua/weapons/weapon_ace_slam/init.lua +++ b/lua/weapons/weapon_ace_slam/init.lua @@ -15,7 +15,7 @@ function SWEP:DoAmmoStatDisplay() local MaxPen = (Energy.Penetration / bdata.SlugPenArea) * ACF.KEtoRHA sendInfo = sendInfo .. string.format(", %.1fmm pen", MaxPen) - self:GetOwner():SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 10)", sendInfo)) + ACE_SendNotification(self:GetOwner(), sendInfo, 10) end function SWEP:Equip() diff --git a/lua/weapons/weapon_ace_slam/shared.lua b/lua/weapons/weapon_ace_slam/shared.lua index 8a5de6c4..e74e39e0 100644 --- a/lua/weapons/weapon_ace_slam/shared.lua +++ b/lua/weapons/weapon_ace_slam/shared.lua @@ -42,10 +42,6 @@ SWEP.Primary.DefaultClip = 8 SWEP.Primary.Automatic = 0 SWEP.Primary.Ammo = "Grenade" -SWEP.Secondary.Ammo = "none" -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSoundEnabled = 1 SWEP.AimOffset = Vector(0, 0, 0) diff --git a/lua/weapons/weapon_ace_smokegrenade/init.lua b/lua/weapons/weapon_ace_smokegrenade/init.lua index 2cd214ce..dd20f5c8 100644 --- a/lua/weapons/weapon_ace_smokegrenade/init.lua +++ b/lua/weapons/weapon_ace_smokegrenade/init.lua @@ -9,7 +9,7 @@ function SWEP:DoAmmoStatDisplay() local sendInfo = string.format( "Smoke Grenade") sendInfo = sendInfo .. string.format(", 10m radius") - self:GetOwner():SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 10)", sendInfo)) + ACE_SendNotification(self:GetOwner(), sendInfo, 10) end function SWEP:Equip() diff --git a/lua/weapons/weapon_ace_smokegrenade/shared.lua b/lua/weapons/weapon_ace_smokegrenade/shared.lua index 2526ce40..06285d0a 100644 --- a/lua/weapons/weapon_ace_smokegrenade/shared.lua +++ b/lua/weapons/weapon_ace_smokegrenade/shared.lua @@ -35,10 +35,6 @@ SWEP.Primary.DefaultClip = 5 SWEP.Primary.Automatic = false SWEP.Primary.Ammo = "Grenade" -SWEP.Secondary.Ammo = "none" -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.JustDeployed = true function SWEP:Deploy() diff --git a/lua/weapons/weapon_ace_tmp/shared.lua b/lua/weapons/weapon_ace_tmp/shared.lua index 6228ee46..1aaf553e 100644 --- a/lua/weapons/weapon_ace_tmp/shared.lua +++ b/lua/weapons/weapon_ace_tmp/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/tmp_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_ump45/shared.lua b/lua/weapons/weapon_ace_ump45/shared.lua index 8937c620..77de1fd3 100644 --- a/lua/weapons/weapon_ace_ump45/shared.lua +++ b/lua/weapons/weapon_ace_ump45/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/ump45_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_usp/shared.lua b/lua/weapons/weapon_ace_usp/shared.lua index 04946c42..1fef040c 100644 --- a/lua/weapons/weapon_ace_usp/shared.lua +++ b/lua/weapons/weapon_ace_usp/shared.lua @@ -23,7 +23,6 @@ SWEP.Primary.Automatic = false SWEP.ReloadSound = "Weapon_Pistol.Reload" - SWEP.ZoomFOV = 60 SWEP.HasScope = false --True if the weapon has a sniper-style scope diff --git a/lua/weapons/weapon_ace_xm1014/shared.lua b/lua/weapons/weapon_ace_xm1014/shared.lua index a662cf05..d536a875 100644 --- a/lua/weapons/weapon_ace_xm1014/shared.lua +++ b/lua/weapons/weapon_ace_xm1014/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/xm1014_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 10 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "Weapon_Pistol.Reload" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound diff --git a/lua/weapons/weapon_ace_xm25/shared.lua b/lua/weapons/weapon_ace_xm25/shared.lua index 0b4ac14f..fdc6f98e 100644 --- a/lua/weapons/weapon_ace_xm25/shared.lua +++ b/lua/weapons/weapon_ace_xm25/shared.lua @@ -19,9 +19,6 @@ SWEP.Primary.Sound = "ace_weapons/sweps/multi_sound/xm25_multi.mp3" SWEP.Primary.LightScale = 200 --Muzzleflash light radius SWEP.Primary.BulletCount = 1 --Number of bullets to fire each shot, used for shotguns -SWEP.Secondary.ClipSize = -1 -SWEP.Secondary.DefaultClip = -1 - SWEP.ReloadSound = "weapons/amr/sniper_reload.wav" --Sound other players hear when you reload - this is NOT your first-person sound --Most models have a built-in first-person reload sound @@ -87,7 +84,7 @@ function SWEP:SecondaryAttack() self.FuseDelay = time > 0.07 and time or 0 end - owner:SendLua(string.format("GAMEMODE:AddNotify(%q, \"NOTIFY_HINT\", 2)", "Fuse Delay: " .. (self.FuseDelay > 0 and (math.Round(self.FuseDelay * 110) .. " m") or "None"))) + ACE_SendNotification(owner, "Fuse Delay: " .. (self.FuseDelay > 0 and (math.Round(self.FuseDelay * 110) .. " m") or "None"), 2) return end diff --git a/materials/models/missiles/Rack2Down_e.vtf b/materials/models/missiles/Rack2Down_e.vtf new file mode 100644 index 00000000..882291a7 Binary files /dev/null and b/materials/models/missiles/Rack2Down_e.vtf differ diff --git a/materials/models/missiles/Rack2Down_n.vtf b/materials/models/missiles/Rack2Down_n.vtf new file mode 100644 index 00000000..cdcaf5af Binary files /dev/null and b/materials/models/missiles/Rack2Down_n.vtf differ diff --git a/materials/models/missiles/Rack2Down_rgb.vtf b/materials/models/missiles/Rack2Down_rgb.vtf new file mode 100644 index 00000000..2bf5c2df Binary files /dev/null and b/materials/models/missiles/Rack2Down_rgb.vtf differ diff --git a/materials/models/missiles/Rack4Down_e.vtf b/materials/models/missiles/Rack4Down_e.vtf new file mode 100644 index 00000000..70c10718 Binary files /dev/null and b/materials/models/missiles/Rack4Down_e.vtf differ diff --git a/materials/models/missiles/Rack4Down_n.vtf b/materials/models/missiles/Rack4Down_n.vtf new file mode 100644 index 00000000..43c17966 Binary files /dev/null and b/materials/models/missiles/Rack4Down_n.vtf differ diff --git a/materials/models/missiles/Rack4Down_rgb.vtf b/materials/models/missiles/Rack4Down_rgb.vtf new file mode 100644 index 00000000..de104771 Binary files /dev/null and b/materials/models/missiles/Rack4Down_rgb.vtf differ diff --git a/materials/models/missiles/Rack4mat_e.vtf b/materials/models/missiles/Rack4mat_e.vtf new file mode 100644 index 00000000..ee81c067 Binary files /dev/null and b/materials/models/missiles/Rack4mat_e.vtf differ diff --git a/materials/models/missiles/Rack4mat_n.vtf b/materials/models/missiles/Rack4mat_n.vtf new file mode 100644 index 00000000..c4f62f9c Binary files /dev/null and b/materials/models/missiles/Rack4mat_n.vtf differ diff --git a/materials/models/missiles/Rack4mat_rgb.vtf b/materials/models/missiles/Rack4mat_rgb.vtf new file mode 100644 index 00000000..d9fd1396 Binary files /dev/null and b/materials/models/missiles/Rack4mat_rgb.vtf differ diff --git a/materials/models/missiles/rack2Down.vmt b/materials/models/missiles/rack2Down.vmt new file mode 100644 index 00000000..59b2d2e0 --- /dev/null +++ b/materials/models/missiles/rack2Down.vmt @@ -0,0 +1,35 @@ +VertexLitGeneric +{ + $basetexture "models/missiles/rack2down_rgb" + $bumpmap "models/missiles/rack2down_n" + + $envmap "/specularity_00" + $normalmapalphaenvmapmask 1 + $envmaptint "[0.10 0.10 0.10]" + + $phong 1 + $phongexponenttexture "models/missiles/rack2down_e" + $phongfresnelranges "[1 0.1 0]" + $phongalbedotint 1 + $phongalbedoboost 10 + + $rimlight 1 + $rimlightexponent 100 + $rimlightboost 1 + + $color2 "[0 0 0]" + $blendtintbybasealpha 1 + + $rimmask 1 + + Proxies + { + MwEnvMapTint + { + min 0 + max 1 + envmap "\specularity_00" + color "[0.098 0.098 0.098]" + } + } +} \ No newline at end of file diff --git a/materials/models/missiles/rack4Down.vmt b/materials/models/missiles/rack4Down.vmt new file mode 100644 index 00000000..63d1661e --- /dev/null +++ b/materials/models/missiles/rack4Down.vmt @@ -0,0 +1,35 @@ +VertexLitGeneric +{ + $basetexture "models/missiles/rack4down_rgb" + $bumpmap "models/missiles/rack4down_n" + + $envmap "/specularity_00" + $normalmapalphaenvmapmask 1 + $envmaptint "[0.10 0.10 0.10]" + + $phong 1 + $phongexponenttexture "models/missiles/rack4down_e" + $phongfresnelranges "[1 0.1 0]" + $phongalbedotint 1 + $phongalbedoboost 10 + + $rimlight 1 + $rimlightexponent 100 + $rimlightboost 1 + + $color2 "[0 0 0]" + $blendtintbybasealpha 1 + + $rimmask 1 + + Proxies + { + MwEnvMapTint + { + min 0 + max 1 + envmap "\specularity_00" + color "[0.098 0.098 0.098]" + } + } +} \ No newline at end of file diff --git a/materials/models/missiles/rack4mat.vmt b/materials/models/missiles/rack4mat.vmt new file mode 100644 index 00000000..2ff6f9f0 --- /dev/null +++ b/materials/models/missiles/rack4mat.vmt @@ -0,0 +1,35 @@ +VertexLitGeneric +{ + $basetexture "models/missiles/rack4mat_rgb" + $bumpmap "models/missiles/rack4mat_n" + + $envmap "/specularity_00" + $normalmapalphaenvmapmask 1 + $envmaptint "[0.10 0.10 0.10]" + + $phong 1 + $phongexponenttexture "models/missiles/rack4mat_e" + $phongfresnelranges "[1 0.1 0]" + $phongalbedotint 1 + $phongalbedoboost 10 + + $rimlight 1 + $rimlightexponent 100 + $rimlightboost 1 + + $color2 "[0 0 0]" + $blendtintbybasealpha 1 + + $rimmask 1 + + Proxies + { + MwEnvMapTint + { + min 0 + max 1 + envmap "\specularity_00" + color "[0.098 0.098 0.098]" + } + } +} \ No newline at end of file diff --git a/materials/models/missiles/rackMaterial.vmt b/materials/models/missiles/rackMaterial.vmt new file mode 100644 index 00000000..ffc455d6 --- /dev/null +++ b/materials/models/missiles/rackMaterial.vmt @@ -0,0 +1,35 @@ +VertexLitGeneric +{ + $basetexture "models/missiles/rackmaterial_rgb" + $bumpmap "models/missiles/rackmaterial_n" + + $envmap "/specularity_00" + $normalmapalphaenvmapmask 1 + $envmaptint "[0.10 0.10 0.10]" + + $phong 1 + $phongexponenttexture "models/missiles/rackmaterial_e" + $phongfresnelranges "[1 0.1 0]" + $phongalbedotint 1 + $phongalbedoboost 10 + + $rimlight 1 + $rimlightexponent 100 + $rimlightboost 1 + + $color2 "[0 0 0]" + $blendtintbybasealpha 1 + + $rimmask 1 + + Proxies + { + MwEnvMapTint + { + min 0 + max 1 + envmap "\specularity_00" + color "[0.098 0.098 0.098]" + } + } +} \ No newline at end of file diff --git a/materials/models/missiles/rackMaterial_e.vtf b/materials/models/missiles/rackMaterial_e.vtf new file mode 100644 index 00000000..3db64a46 Binary files /dev/null and b/materials/models/missiles/rackMaterial_e.vtf differ diff --git a/materials/models/missiles/rackMaterial_n.vtf b/materials/models/missiles/rackMaterial_n.vtf new file mode 100644 index 00000000..a3f1d5e3 Binary files /dev/null and b/materials/models/missiles/rackMaterial_n.vtf differ diff --git a/materials/models/missiles/rackMaterial_rgb.vtf b/materials/models/missiles/rackMaterial_rgb.vtf new file mode 100644 index 00000000..47e8cfbf Binary files /dev/null and b/materials/models/missiles/rackMaterial_rgb.vtf differ diff --git a/materials/models/missiles/rackTop.vmt b/materials/models/missiles/rackTop.vmt new file mode 100644 index 00000000..1fdcaee8 --- /dev/null +++ b/materials/models/missiles/rackTop.vmt @@ -0,0 +1,23 @@ +VertexLitGeneric +{ + $basetexture "models/missiles/rackTop_rgb" + + $phong 1 + + $rimlight 1 + $rimlightexponent 100 + $rimlightboost 1 + + $rimmask 1 + + Proxies + { + MwEnvMapTint + { + min 0 + max 1 + envmap "\specularity_00" + color "[0.098 0.098 0.098]" + } + } +} \ No newline at end of file diff --git a/materials/models/missiles/rackTop_rgb.vtf b/materials/models/missiles/rackTop_rgb.vtf new file mode 100644 index 00000000..f6d644f6 Binary files /dev/null and b/materials/models/missiles/rackTop_rgb.vtf differ diff --git a/models/missiles/KornetRack2.dx80.vtx b/models/missiles/KornetRack2.dx80.vtx new file mode 100644 index 00000000..359d24bf Binary files /dev/null and b/models/missiles/KornetRack2.dx80.vtx differ diff --git a/models/missiles/KornetRack2.dx90.vtx b/models/missiles/KornetRack2.dx90.vtx new file mode 100644 index 00000000..0498bf84 Binary files /dev/null and b/models/missiles/KornetRack2.dx90.vtx differ diff --git a/models/missiles/KornetRack2.mdl b/models/missiles/KornetRack2.mdl new file mode 100644 index 00000000..3ea4fc23 Binary files /dev/null and b/models/missiles/KornetRack2.mdl differ diff --git a/models/missiles/KornetRack2.phy b/models/missiles/KornetRack2.phy new file mode 100644 index 00000000..608b248a Binary files /dev/null and b/models/missiles/KornetRack2.phy differ diff --git a/models/missiles/KornetRack2.sw.vtx b/models/missiles/KornetRack2.sw.vtx new file mode 100644 index 00000000..259804e7 Binary files /dev/null and b/models/missiles/KornetRack2.sw.vtx differ diff --git a/models/missiles/KornetRack2.vvd b/models/missiles/KornetRack2.vvd new file mode 100644 index 00000000..8f994e37 Binary files /dev/null and b/models/missiles/KornetRack2.vvd differ diff --git a/models/missiles/KornetRack4.dx80.vtx b/models/missiles/KornetRack4.dx80.vtx new file mode 100644 index 00000000..4feacc7c Binary files /dev/null and b/models/missiles/KornetRack4.dx80.vtx differ diff --git a/models/missiles/KornetRack4.dx90.vtx b/models/missiles/KornetRack4.dx90.vtx new file mode 100644 index 00000000..9d1f5d9d Binary files /dev/null and b/models/missiles/KornetRack4.dx90.vtx differ diff --git a/models/missiles/KornetRack4.mdl b/models/missiles/KornetRack4.mdl new file mode 100644 index 00000000..749e6871 Binary files /dev/null and b/models/missiles/KornetRack4.mdl differ diff --git a/models/missiles/KornetRack4.phy b/models/missiles/KornetRack4.phy new file mode 100644 index 00000000..6f0d7722 Binary files /dev/null and b/models/missiles/KornetRack4.phy differ diff --git a/models/missiles/KornetRack4.sw.vtx b/models/missiles/KornetRack4.sw.vtx new file mode 100644 index 00000000..8cebbb20 Binary files /dev/null and b/models/missiles/KornetRack4.sw.vtx differ diff --git a/models/missiles/KornetRack4.vvd b/models/missiles/KornetRack4.vvd new file mode 100644 index 00000000..cc74d696 Binary files /dev/null and b/models/missiles/KornetRack4.vvd differ diff --git a/sound/acf_other/ricochets/props/small/close/richo1.mp3 b/sound/acf_other/ricochets/props/small/close/richo1.mp3 index 4559337b..aa589e38 100644 Binary files a/sound/acf_other/ricochets/props/small/close/richo1.mp3 and b/sound/acf_other/ricochets/props/small/close/richo1.mp3 differ diff --git a/sound/acf_other/ricochets/props/small/close/richo2.mp3 b/sound/acf_other/ricochets/props/small/close/richo2.mp3 index 357e1568..9b03e851 100644 Binary files a/sound/acf_other/ricochets/props/small/close/richo2.mp3 and b/sound/acf_other/ricochets/props/small/close/richo2.mp3 differ