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