From 64aa800a34a8651098ca67576f8814b7a616a028 Mon Sep 17 00:00:00 2001 From: LiddulBOFH <13317534+LiddulBOFH@users.noreply.github.com> Date: Sat, 25 May 2024 15:37:20 -0500 Subject: [PATCH] Turret-Gun link, New E2/SF function, Vertical drive change Guns are now able to be linked to turrets, doing so will make the gun check if it is aligned with the target angle of the turret (regardless of arc limits), and if it is not aligned (outside of 5 degrees to target) it will block firing. If the linked turret is inactive, it will also block firing (for an easy gun/traverse lock solution) Exposed the internal rotator with a new starfall/expression 2 function - E2: Turret:acfGetTurretRotator() - SF: Turret:acfGetTurretRotator() Also a new function to get a normalized direction that the turret is facing, which I just didn't remove after adding the above functions - E2: Turret:acfGetTurretForward() Changed the small horizontal drive model to the less expensive version of the cylinder hologram Doubled the max teeth count for vertical drives, effectively halving the top speed they could previously achieve, which was a bit ridiculous at times --- lua/acf/entities/turrets/turrets.lua | 22 +++++++-- lua/entities/acf_gun/init.lua | 29 ++++++++++++ lua/entities/acf_turret/init.lua | 1 + .../core/custom/acffunctions.lua | 45 +++++++++++++------ .../core/custom/cl_acfdescriptions.lua | 2 + lua/starfall/libs_sh/acffunctions.lua | 16 +++++++ 6 files changed, 99 insertions(+), 16 deletions(-) diff --git a/lua/acf/entities/turrets/turrets.lua b/lua/acf/entities/turrets/turrets.lua index bff7e173d..1605c9b25 100644 --- a/lua/acf/entities/turrets/turrets.lua +++ b/lua/acf/entities/turrets/turrets.lua @@ -92,7 +92,7 @@ do -- Turret drives local OverweightMod = 1 if TurretData.TotalMass > TurretData.MaxMass then - OverweightMod = 1 - (((TurretData.TotalMass - TurretData.MaxMass) / TurretData.MaxMass) / 2) + OverweightMod = math.max(0,1 - (((TurretData.TotalMass - TurretData.MaxMass) / TurretData.MaxMass) / 2)) end -- Slewing ring friction moment caused by load (kNm) @@ -150,7 +150,7 @@ do -- Turret drives Name = "Horizontal Turret", 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 <= 12.5u, for RWS or other small turrets + ModelSmall = "models/holograms/cylinder.mdl", -- To be used for diameters <= 12.5u, for RWS or other small turrets Mass = 34, -- At default size, this is the mass of the turret ring. Will scale up/down with diameter difference Size = { @@ -207,6 +207,14 @@ do -- Turret drives end end, + GetWorldTarget = function(Turret) + if Turret.Manual then + return Turret:LocalToWorldAngles(Angle(0, Turret.DesiredDeg, 0)) + else + return Turret:LocalToWorldAngles(Turret:WorldToLocalAngles(Turret.DesiredAngle)) + end + end, + SetRotatorAngle = function(Turret) Turret.Rotator:SetAngles(Turret:LocalToWorldAngles(Angle(0, Turret.CurrentAngle, 0))) end @@ -234,7 +242,7 @@ do -- Turret drives Teeth = { -- Used to give a final teeth count with size Min = 8, - Max = 384 + Max = 768 }, Armor = { @@ -277,6 +285,14 @@ do -- Turret drives end end, + GetWorldTarget = function(Turret) + if Turret.Manual then + return Turret:LocalToWorldAngles(Angle(Turret.DesiredDeg, 0, 0)) + else + return Turret:LocalToWorldAngles(Turret:WorldToLocalAngles(Turret.DesiredAngle)) + end + end, + SetRotatorAngle = function(Turret) Turret.Rotator:SetAngles(Turret:LocalToWorldAngles(Angle(Turret.CurrentAngle, 0, 0))) end diff --git a/lua/entities/acf_gun/init.lua b/lua/entities/acf_gun/init.lua index 0ddb8213c..b721215e3 100644 --- a/lua/entities/acf_gun/init.lua +++ b/lua/entities/acf_gun/init.lua @@ -246,6 +246,7 @@ do -- Spawn and Update functions -------------------------------- Entity.CurrentShot = 0 Entity.TotalAmmo = 0 Entity.BulletData = EMPTY + Entity.TurretLink = false Entity.DataStore = Entities.GetArguments("acf_gun") UpdateWeapon(Entity, Data, Class, Weapon) @@ -413,6 +414,20 @@ do -- Metamethods -------------------------------- return false, "This weapon is not linked to this crate." end) + ACF.RegisterClassLink("acf_gun", "acf_turret", function(This, Turret) + This.TurretLink = true + This.Turret = Turret + + return true, "Weapon linked successfully." + end) + + ACF.RegisterClassUnlink("acf_gun", "acf_turret", function(This, _) + This.TurretLink = false + This.Turret = nil + + return true, "Weapon unlinked successfully." + end) + ACF.AddInputAction("acf_gun", "Fire", function(Entity, Value) local Bool = tobool(Value) @@ -506,6 +521,12 @@ do -- Metamethods -------------------------------- return false end + if self.TurretLink and IsValid(self.Turret) then -- Special link to a turret, will block the gun from firing if the gun is not aligned with the turret's target angle + local Turret = self.Turret + if not Turret.Active then return false end + + if self:GetForward():Dot(Turret.SlewFuncs.GetWorldTarget(Turret):Forward()) < 0.9961 then return false end + end if HookRun("ACF_FireShell", self) == false then return false end -- Something hooked into ACF_FireShell said no return true @@ -746,6 +767,10 @@ do -- Metamethods -------------------------------- duplicator.StoreEntityModifier(self, "ACFCrates", Entities) end + if IsValid(self.Turret) then + duplicator.StoreEntityModifier(self, "ACFTurret", {self.Turret:EntIndex()}) + end + -- Wire dupe info self.BaseClass.PreEntityCopy(self) end @@ -772,6 +797,10 @@ do -- Metamethods -------------------------------- EntMods.ACFCrates = nil end + if EntMods.ACFTurret and next(EntMods.ACFTurret) then + self:Link(CreatedEntities[EntMods.ACFTurret[1]]) + end + self.BaseClass.PostEntityPaste(self, Player, Ent, CreatedEntities) end end ----------------------------------------- diff --git a/lua/entities/acf_turret/init.lua b/lua/entities/acf_turret/init.lua index 506ac1afe..3e239d8b8 100644 --- a/lua/entities/acf_turret/init.lua +++ b/lua/entities/acf_turret/init.lua @@ -298,6 +298,7 @@ do -- Spawn and Update funcs Entity.Rotator = Rotator Rotator.Turret = Entity + Rotator.Owner = Entity UpdateTurret(Entity, Data, Class, Turret) diff --git a/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua b/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua index 75037a70f..2766b96c6 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua @@ -149,7 +149,7 @@ e2function number entity:acfIsGun() end -- Returns 1 if the entity is an ACF turret -e2function number entity:acfIsGun() +e2function number entity:acfIsTurret() if not validPhysics(this) then return 0 end if RestrictInfo(self, this) then return 0 end @@ -1179,6 +1179,25 @@ e2function number entity:acfGetTurretAngle() return math.Round(-this.CurrentAngle,4) end +-- Returns the turret's forward (using the rotator) +e2function vector entity:acfGetTurretForward() + if not this.IsACFTurret then return Vector() end + if RestrictInfo(self, this) then return Vector() end + + if not IsValid(this.Rotator) then return this:GetForward() end + + return this.Rotator:GetForward() +end + +e2function entity entity:acfGetTurretRotator() + if not this.IsACFTurret then return end + if RestrictInfo(self, this) then return end + + if not IsValid(this.Rotator) then return end + + return this.Rotator +end + -- Returns the turret's linked gyroscope e2function entity entity:acfGetTurretGyro() if not this.IsACFTurret then return end @@ -1197,48 +1216,48 @@ end -- Returns the turret's loaded mass, in kg e2function number entity:acfGetTurretMass() - if not this.IsACFTurret then return end - if RestrictInfo(self, this) then return end + if not this.IsACFTurret then return 0 end + if RestrictInfo(self, this) then return 0 end return math.Round(this.TurretData.TotalMass,2) end -- Returns the turret's center of mass, local to the turret e2function vector entity:acfGetTurretMassCenter() - if not this.IsACFTurret then return end - if RestrictInfo(self, this) then return end + if not this.IsACFTurret then return Vector() end + if RestrictInfo(self, this) then return Vector() end return this:WorldToLocal(this.Rotator:LocalToWorld(this.TurretData.LocalCoM)) end -- Returns the turret's current slew rate, in degrees/second e2function number entity:acfGetTurretSlewRate() - if not this.IsACFTurret then return end - if RestrictInfo(self, this) then return end + if not this.IsACFTurret then return 0 end + if RestrictInfo(self, this) then return 0 end return math.Round(-this.SlewRate / Clock.DeltaTime,2) end -- Returns the turret's top slew rate, in degrees/second e2function number entity:acfGetTurretMaxSlewRate() - if not this.IsACFTurret then return end - if RestrictInfo(self, this) then return end + if not this.IsACFTurret then return 0 end + if RestrictInfo(self, this) then return 0 end return math.Round(this.MaxSlewRate,2) end -- Returns the turret's acceleration, in degrees/second ^ 2 e2function number entity:acfGetTurretSlewAccel() - if not this.IsACFTurret then return end - if RestrictInfo(self, this) then return end + if not this.IsACFTurret then return 0 end + if RestrictInfo(self, this) then return 0 end return math.Round(this.SlewAccel,4) end -- Returns whether or not the turret is stabilized, and the percentage (0-1) e2function number entity:acfGetTurretStabilized() - if not this.IsACFTurret then return end - if RestrictInfo(self, this) then return end + if not this.IsACFTurret then return 0 end + if RestrictInfo(self, this) then return 0 end return this.Stabilized and this.StabilizeAmount or 0 end diff --git a/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua b/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua index ead39a7ff..b53ac4d61 100644 --- a/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua +++ b/lua/entities/gmod_wire_expression2/core/custom/cl_acfdescriptions.lua @@ -121,6 +121,8 @@ E2Desc["acfTotalAmmoCount(e:)"] = "Returns the number of rounds in all ammo crat -- Turret functions E2Desc["acfGetTurretAngle(e:)"] = "Returns the turret's current angle, relative to home." +E2Desc["acfGetTurretForward(e:)"] = "Returns the turret's forward direction." +E2Desc["acfGetTurretRotator(e:)"] = "Returns the turret's rotator." E2Desc["acfGetTurretGyro(e:)"] = "Returns the turret's linked gyroscope, if available." E2Desc["acfGetTurretMotor(e:)"] = "Returns the turret's linked motor, if available." E2Desc["acfGetTurretMass(e:)"] = "Returns the turret's loaded mass, in kg." diff --git a/lua/starfall/libs_sh/acffunctions.lua b/lua/starfall/libs_sh/acffunctions.lua index df5b55c64..6f2e30cb6 100644 --- a/lua/starfall/libs_sh/acffunctions.lua +++ b/lua/starfall/libs_sh/acffunctions.lua @@ -2498,6 +2498,22 @@ if SERVER then return math.Round(-This.CurrentAngle,4) end + --- Returns the turret's rotator + -- @server + -- @return Entity The turret's rotator + function ents_methods:acfGetTurretRotator() + CheckType(self, ents_metatable) + + local This = unwrap(self) + + if not (IsACFEntity(This) and (This.IsACFTurret or false)) then SF.Throw("Entity is not valid", 2) end + if RestrictInfo(This) then return end + + CheckPerms(instance, This, "entities.acf") + + return IsValid(This.Rotator) and This.Rotator or nil + end + --- Returns the gyroscope linked to the turret -- @server -- @return Entity? The gyroscope linked to the turret, if available, nil if not