Skip to content

Commit

Permalink
Turret-Gun link, New E2/SF function, Vertical drive change
Browse files Browse the repository at this point in the history
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
  • Loading branch information
LiddulBOFH committed May 25, 2024
1 parent 2c3a4b2 commit 64aa800
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 16 deletions.
22 changes: 19 additions & 3 deletions lua/acf/entities/turrets/turrets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 = {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -234,7 +242,7 @@ do -- Turret drives

Teeth = { -- Used to give a final teeth count with size
Min = 8,
Max = 384
Max = 768
},

Armor = {
Expand Down Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions lua/entities/acf_gun/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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 -----------------------------------------
Expand Down
1 change: 1 addition & 0 deletions lua/entities/acf_turret/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ do -- Spawn and Update funcs

Entity.Rotator = Rotator
Rotator.Turret = Entity
Rotator.Owner = Entity

UpdateTurret(Entity, Data, Class, Turret)

Expand Down
45 changes: 32 additions & 13 deletions lua/entities/gmod_wire_expression2/core/custom/acffunctions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
16 changes: 16 additions & 0 deletions lua/starfall/libs_sh/acffunctions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 64aa800

Please sign in to comment.