Skip to content

Commit

Permalink
Optimize ObjectiveArrow.lua (FAForever#4376)
Browse files Browse the repository at this point in the history
  • Loading branch information
4z0t authored Nov 18, 2022
1 parent beb6c01 commit 36e2535
Showing 1 changed file with 38 additions and 35 deletions.
73 changes: 38 additions & 35 deletions lua/objectiveArrow.lua
Original file line number Diff line number Diff line change
@@ -1,63 +1,66 @@
local Entity = import("/lua/sim/entity.lua").Entity

---@class ObjectiveArrowSpec
---@field AttachTo? Object
---@field Size? number defaults to `1.0`

---@class ObjectiveArrow : Entity
ObjectiveArrow = Class(Entity) {

---@param self ObjectiveArrow
---@param spec table
OnCreate = function(self,spec)
self.BounceTime = 0.0
self.Size = spec.Size or 1.0
---@param spec ObjectiveArrowSpec
OnCreate = function(self, spec)
-- unpack specs
local size = spec.Size or 1.0
local attachTo = spec.AttachTo

local arrowSize = size
self:SetVizToFocusPlayer('Always')
self:SetVizToEnemies('Intel')
self:SetVizToAllies('Never')
self:SetVizToNeutrals('Intel')

self:SetMesh('/meshes/game/arrow_mesh')

local unitScale = 1.0

if spec.AttachTo then
spec.AttachTo.Trash:Add(self)
self:AttachBoneTo(-1,spec.AttachTo,-1)
if attachTo then
attachTo.Trash:Add(self)
self:AttachBoneTo(-1, attachTo, -1)

-- Position at the top of the parent's collision box
local yOff = 0
local extents = spec.AttachTo:GetCollisionExtents()
local extents = attachTo:GetCollisionExtents()
if extents then
-- scale up arrow based on unit's size
unitScale = math.min( extents.Max.x - extents.Min.x, extents.Max.z - extents.Min.z)
unitScale = math.max( unitScale, 1.0 )

yOff = (self.Size * unitScale) / 2.0 + extents.Max.y - spec.AttachTo:GetPosition().y
yOff = yOff + 0.5
else
yOff = spec.Size / 2.0 + 0.5
local extentsMax, extentsMin = extents.Max, extents.Min
local unitSize = math.min(extentsMax.x - extentsMin.x, extentsMax.z - extentsMin.z)
-- scale up arrow size based on unit's extents if it ends up making it larger
if unitSize > 1 then
arrowSize = arrowSize * unitSize
end
yOff = extentsMax.y - attachTo:GetPosition().y
end
yOff = yOff + arrowSize * 0.5 + 0.5

self:SetParentOffset(Vector(0,yOff,0))
self.SavedOffset = yOff;
ForkThread(self.BounceThread,self)
ForkThread(self.BounceThread, self, yOff) -- handles the first `SetParentOffset` from the y offset
end

-- magic 0.4 scaling so spec.Size can be specified in OGrid units
self:SetDrawScale(0.4 * self.Size * unitScale)
self:SetDrawScale(0.4 * arrowSize)
end,

---@param self ObjectiveArrow
BounceThread = function(self)
while true do
if self:BeenDestroyed() then
return
end

--LOG('sin =',math.sin(self.BounceTime))
local yOff = self.SavedOffset + math.sin(self.BounceTime) / 4

self:SetParentOffset( Vector(0,yOff,0) )

---@param yOff number
BounceThread = function(self, yOff)
local vec = Vector(0, yOff, 0)
-- since the bounce change is pi/4, this will end up oscillating with a frequency of 8 like
-- 0 --> sqrt(2)/2 --> 1 --> sqrt(2)/2 --> 0 --> -sqrt(2)/2 --> -1 --> -sqrt(2)/2 --> 0
local bounceTime = 0
local bounceChng = math.pi * 0.25
while not self:BeenDestroyed() do
vec.y = yOff + math.sin(bounceTime) * 0.25
self:SetParentOffset(vec)
WaitSeconds(0.1)
self.BounceTime = self.BounceTime + math.pi * 0.25

bounceTime = bounceTime + bounceChng
end
end,
}
}

0 comments on commit 36e2535

Please sign in to comment.