Skip to content

Commit

Permalink
Ballistic computers, minor effect change, minor turret changes
Browse files Browse the repository at this point in the history
The ballistic computers are finally available!
These link to a single weapon to get the ballistic data, which is then used in calculations
- Direct fire: Will calculate the appropriate angle to point the gun in, in order to hit a target the quickest way possible
- Indirect fire: Will calculate the appropriate angle to point the gun in, usually up, in order to hit a target behind cover

Adjusted the clientside bullet effect lifetime to 45 seconds as it would often expire during testing the indirect fire computer, and you would never see the round land

Tilting a horizontal ring now adjusts the friction to be higher the more its tilted, maxing out on its side, and being unusable upside down
Vertical drives are unaffected

Disabled rendering of the rotator entity as you would see the error shadow due to no model being applied

Minor style update to the turret menu
  • Loading branch information
LiddulBOFH committed Feb 5, 2024
1 parent 7bf1a49 commit 6dfc331
Show file tree
Hide file tree
Showing 9 changed files with 506 additions and 170 deletions.
7 changes: 4 additions & 3 deletions lua/acf/entities/turrets/turret_menu_cl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ do -- Turret ring
TotalMass = 0,
RingSize = Data.Size.Base,
RingHeight = TurretClass.GetRingHeight({Type = "Turret-H",Ratio = Data.Size.Ratio},Data.Size.Base),
LocalCoM = Vector()
LocalCoM = Vector(),
Tilt = 1
}

local RingSize = Menu:AddSlider("Ring diameter (gmu)", Data.Size.Min, Data.Size.Max, 2)
Expand Down Expand Up @@ -238,7 +239,7 @@ do -- Turret Motors
if TurretData.Ready == false then return end

--local Info = TurretClass.CalcInfo({Mass = TurretData.Mass, Size = TurretData.Size, Teeth = TurretData.TurretTeeth, TurretClass = TurretData.Type, Distance = TurretData.Distance},TurretClass.HandGear)
local Info = TurretClass.CalcSpeed({TotalMass = TurretData.Mass, RingSize = TurretData.Size, Teeth = TurretData.TurretTeeth, TurretClass = TurretData.Type, LocalCoM = Vector(TurretData.Distance,0,0), RingHeight = TurretData.RingHeight},
local Info = TurretClass.CalcSpeed({Tilt = 1, TotalMass = TurretData.Mass, RingSize = TurretData.Size, Teeth = TurretData.TurretTeeth, TurretClass = TurretData.Type, LocalCoM = Vector(TurretData.Distance,0,0), RingHeight = TurretData.RingHeight},
TurretClass.HandGear)

Panel:SetText(HandcrankText:format(math.Round(Info.MaxSlewRate,2),math.Round(Info.SlewAccel,4)))
Expand All @@ -251,7 +252,7 @@ do -- Turret Motors
--local Info = TurretClass.CalcInfo({Mass = TurretData.Mass, Size = TurretData.Size, Teeth = TurretData.TurretTeeth, TurretClass = TurretData.Type, Distance = TurretData.Distance},
--{Teeth = TurretData.MotorTeeth, Speed = Data.Speed, Torque = TurretData.Torque, Efficiency = Data.Efficiency})

local Info = TurretClass.CalcSpeed({TotalMass = TurretData.Mass, RingSize = TurretData.Size, Teeth = TurretData.TurretTeeth, TurretClass = TurretData.Type, LocalCoM = Vector(TurretData.Distance,0,0), RingHeight = TurretData.RingHeight},
local Info = TurretClass.CalcSpeed({Tilt = 1, TotalMass = TurretData.Mass, RingSize = TurretData.Size, Teeth = TurretData.TurretTeeth, TurretClass = TurretData.Type, LocalCoM = Vector(TurretData.Distance,0,0), RingHeight = TurretData.RingHeight},
{Teeth = TurretData.MotorTeeth, Speed = Data.Speed, Torque = TurretData.Torque, Efficiency = Data.Efficiency, Accel = Data.Accel})

Panel:SetText(MotorText:format(math.Round(Info.MaxSlewRate,2),math.Round(Info.SlewAccel,4)))
Expand Down
57 changes: 35 additions & 22 deletions lua/acf/entities/turrets/turrets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ do -- Turret drives
- RingSize : Diameter of ring (gmu)
- RingHeight: Height of ring (gmu)
- Teeth : Number of teeth of the turret ring
- Tilt : 1 - On axis, 0 - Off axis, scales between
PowerData should include: (look at HandGear above for example, that can be directly fed to this function)
- Teeth : Number of teeth of gear on input source
Expand All @@ -92,10 +93,13 @@ do -- Turret drives
local Weight = (TurretData.TotalMass * 9.81) / 1000
local Mz = 0 -- Nm resistance to torque

local Mk,Fa,Fr

if TurretData.TurretClass == "Turret-H" then
Mk = Weight * OffBaseDistance -- Sum of tilting moments (kNm) (off balance load)
Fa = Weight * math.Clamp(1 - (CoMDistance * 2),0,1) -- Sum of axial dynamic forces (kN) (on balance load)
Mz = 0.006 * 4.4 * (((Mk * 1000) / Diameter) + (Fa / 4.4)) * (Diameter / 2000)
Fa = Weight * math.Clamp(1 - (CoMDistance * 2),0,1) * TurretData.Tilt -- Sum of axial dynamic forces (kN) (on balance load)
Fr = Weight * math.Clamp(1 - (CoMDistance * 2),0,1) * (1 - TurretData.Tilt) * 1.73 -- Sum of radial dynamic forces (kN), 1.73 is the coefficient for prevailing load, which is already determined by CoMDistance and Tilt
Mz = 0.006 * 4.4 * (((Mk * 1000) / Diameter) + (Fa / 4.4) + (Fr / 2)) * (Diameter / 2000)
else
local ZDist = TurretData.LocalCoM.z * (InchToMm / 1000)

Expand Down Expand Up @@ -138,7 +142,7 @@ do -- Turret drives
Description = "The large stable base of a turret.",
Model = "models/acf/core/t_ring.mdl",
ModelSmall = "models/holograms/hq_cylinder.mdl", -- To be used for diameters < 12u, for RWS or other small turrets
Mass = 25, -- At default size, this is the mass of the turret ring. Will scale up/down with diameter difference
Mass = 34, -- At default size, this is the mass of the turret ring. Will scale up/down with diameter difference

Size = {
Base = 60, -- The default size for the menu
Expand Down Expand Up @@ -387,55 +391,64 @@ end

-- I will eventually work on this. Eventually.

--[[

do -- Turret computers
Turrets.Register("4-Computer",{
Name = "Computers",
Description = "Computer capable of calculating the optimal angle to hit a target.\nHas a delay between uses.",
Description = "Computer capable of calculating the optimal angle to hit a target.\nLinks to a weapon to get bullet data, required for ballistics calculations.",
Entity = "acf_turret_computer",
CreateMenu = ACF.CreateTurretComputerMenu,
LimitConVar = {
Name = "_acf_turret_computer",
Amount = 20,
Amount = 4,
Text = "Maximum number of ACF turret computers a player can create."
},
})
]]

--[[
Ballistic computers that should be linked to a gun to gather bulletdata, and have a Calculate input
When Calculate is triggered, Thinking flag is set so only one run can occur at once
After calculation is done, output Firing Solution [ANGLE] (global), Flight Time [NUMBER]
]]
--[[
do -- Computers
]]

do -- Computers
Turrets.RegisterItem("DIR-BalComp","4-Computer",{
Name = "Direct Ballistics Computer",
Description = "A component that is capable of calculating the angle required to shoot a weapon to hit a spot within view.\nHas a delay between uses.",
Description = "A component that is capable of calculating the angle required to shoot a weapon to hit a spot within view.\nThis is capable of constantly calculating to track a target at a constant velocity, as long as Calculate is true.\nHas a 2s delay between uses.",
Model = "models/acf/core/t_computer.mdl",

Mass = 100,

Delay = 3, -- Time after finishing before another calculation can run
MaxThinkTime = 2, -- After this long the calculation will halt and return early, and return 0 on everything
ThinkTime = 0.05,
CalcError = 0.25, -- Lee-way in units per 100u of lateral distance
ComputerInfo = {
ThinkTime = 0.04, -- Speed of the actual think time
MaxThinkTime = 4, -- Maximum time to spend on a simulation
DeltaTime = 0.2, -- Simulation speed (affects calculations directly, higher numbers mean the simulation runs faster but will be less accurate)
CalcError = 0.25, -- Lee-way in units per 100u of lateral distance
HighArc = false, -- Starts with simulation pointed directly at target if false, otherwise starts pointing up and moves down
Constant = true, -- Will constantly run as long as Calculate is 1
Bulk = 8, -- Number of calculations to perform per tick
Delay = 2 -- Time after finishing before another calculation can run
},
})

Turrets.RegisterItem("IND-BalComp","4-Computer",{
Name = "Indirect Ballistics Computer",
Description = "A component that is capable of calculating the angle required to shoot a weapon to hit a spot out of view.\nHas a delay between uses.",
Description = "A component that is capable of calculating the angle required to shoot a weapon to hit a spot out of view.\nHas a 3s delay between uses.",
Model = "models/acf/core/t_computer.mdl",

Mass = 150,

Delay = 5,
MaxThinkTime = 7.5,
ThinkTime = 0.1,
CalcError = 3,
ComputerInfo = {
ThinkTime = 0.04, -- Speed of the actual think time
MaxThinkTime = 6, -- Maximum time to spend on a simulation
DeltaTime = 0.06, -- Simulation speed (affects calculations directly, higher numbers mean the simulation runs faster but will be less accurate)
CalcError = 0.05, -- Lee-way in units per 100u of lateral distance
HighArc = true, -- Starts with simulation pointed directly at target if false, otherwise starts pointing up and moves down
Constant = false,
Bulk = 10, -- Number of calculations to perform per tick
Delay = 3, -- Time after finishing before another calculation can run
},
})
end
end]]
end
6 changes: 6 additions & 0 deletions lua/acf/menu/items_cl/turret_menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ local function CreateMenu(Menu)
Menu:AddTitle("Procedural Turrets")
Menu:AddLabel("Warning: Experimental!\nTurret entities are a work in progress, and may lead to some strange events!\nReport any crashes or other issues if you come across them!")

Menu:AddLabel("Typically, place the horizontal turret, and then parent a vertical turret to it to make a fully functional turret. You can parent anything directly to the turret pieces and they will be attached and rotate correctly.")

local ClassList = Menu:AddComboBox()
local ClassDesc = Menu:AddLabel()
local ComponentClass = Menu:AddComboBox()
Expand All @@ -20,6 +22,10 @@ local function CreateMenu(Menu)
local ComponentName = Base:AddTitle()
local ComponentDesc = Base:AddLabel()

Base.ApplySchemeSettings = function(Panel)
Panel:SetBGColor(Color(175,175,175))
end

function ClassList:OnSelect(Index, _, Data)
if self.Selected == Data then return end

Expand Down
2 changes: 1 addition & 1 deletion lua/effects/acf_bullet_effect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ end
function EFFECT:Think()
local Bullet = Bullets[self.Index]

if Bullet and not self.Kill and self.CreateTime > Clock.CurTime - 30 then return true end
if Bullet and not self.Kill and self.CreateTime > Clock.CurTime - 45 then return true end

if Bullet then
if IsValid(Bullet.Tracer) then
Expand Down
19 changes: 16 additions & 3 deletions lua/entities/acf_turret/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,9 @@ do -- Spawn and Update funcs
RingSize = Size,
RingHeight = RingHeight,
TotalMass = 0,
LocalCoM = Vector()
LocalCoM = Vector(),
Tilt = 1,
TurretClass = Data.Turret
}

-- Type-specific functions that differ between horizontal and vertical turret components
Expand Down Expand Up @@ -270,8 +272,9 @@ do -- Spawn and Update funcs
Rotator:SetPos(Entity:GetPos())
Rotator:SetAngles(Entity:GetAngles())
Rotator:SetParent(Entity)
--Rotator:SetModel("models/sprops/misc/origin.mdl")
Rotator:Spawn()
Rotator:SetRenderMode(RENDERMODE_NONE)
Rotator:DrawShadow(false)

Entity.Rotator = Rotator
Rotator.Turret = Entity
Expand Down Expand Up @@ -513,6 +516,16 @@ do -- Spawn and Update funcs
SoundPath = self.Motor.SoundPath
end

-- Scale for being off-axis, further affects friction
local Tilt = 1
if self.Turret == "Turret-V" then
Tilt = math.max(1 - self:GetRight():Dot(Vector(0,0,1)),0)
else
Tilt = math.max(self:GetUp():Dot(Vector(0,0,1)),0)
end

self.TurretData.Tilt = Tilt

local SlewData = self.ClassData.CalcSpeed(self.TurretData,SlewInput)

-- Allowing vertical turret drives to have a small amount of stabilization, but only if they aren't powered and the mass is well balanced
Expand Down Expand Up @@ -947,7 +960,7 @@ do -- Metamethods
if DmgInfo.Attacker and IsValid(DmgInfo.Attacker) then
local Attacker = DmgInfo.Attacker

if ((Attacker:GetClass() == "acf_ammo") or (Attacker:GetClass() == "acf_fueltank")) and (not Contraption.HasAncestor(Attacker,self)) and (Attacker.Exploding == true and (HitRes.Damage >= self.ACF.Health) and (self.Disconnect == false)) then
if ((Attacker:GetClass() == "acf_ammo") or (Attacker:GetClass() == "acf_fueltank")) and (Attacker.Exploding == true and (HitRes.Damage >= self.ACF.Health) and (self.Disconnect == false)) then
self.Disconnect = true

self:SetParent(nil)
Expand Down
8 changes: 4 additions & 4 deletions lua/entities/acf_turret_computer/cl_init.lua
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
DEFINE_BASECLASS("acf_base_scalable")
DEFINE_BASECLASS("acf_base_simple")

include("shared.lua")

language.Add("Cleanup__acf_turret_motor", "ACF Turret Motors")
language.Add("Cleanup__acf_turret_motor", "Cleaned up all ACF turret motors!")
language.Add("SBoxLimit__acf_turret_motor", "You've reached the ACF turret motors limit!")
language.Add("Cleanup__acf_turret_computer", "ACF Ballistic Computer")
language.Add("Cleanup__acf_turret_computer", "Cleaned up all ACF ballistic computers!")
language.Add("SBoxLimit__acf_turret_computer", "You've reached the ACF ballistic computers limit!")
Loading

0 comments on commit 6dfc331

Please sign in to comment.