diff --git a/engine/Sim/Projectile.lua b/engine/Sim/Projectile.lua index 4d2b5aa420..eddb6057f9 100644 --- a/engine/Sim/Projectile.lua +++ b/engine/Sim/Projectile.lua @@ -18,11 +18,15 @@ function Projectile:ChangeDetonateBelowHeight(height) end --- Change the amount of zig-zag in degrees per second +--- +--- You can use `Projectile:GetMaxZigZag()` to retrieve the current zig zag distance. ---@param max number function Projectile:ChangeMaxZigZag(max) end --- Change the frequency of the zig-zag +--- +--- You can use `Projectile:GetZigZagFrequency()` to retrieve the current zig zag frequency. ---@param freq number function Projectile:ChangeZigZagFrequency(freq) end @@ -34,7 +38,7 @@ function Projectile:CreateChildProjectile(blueprint) end --- Returns the speed over ticks instead of over seconds. Multiply by 10 to get the (usually) expected speed value ----@return number +---@return number function Projectile:GetCurrentSpeed() end @@ -43,6 +47,27 @@ end function Projectile:GetCurrentTargetPosition() end +--- Returns the position of the current target as separate coordinates. +---@return number # x +---@return number # y +---@return number # z +function Projectile:GetCurrentTargetPositionXYZ() +end + +--- Returns the zig zag frequency. +--- +--- You can use `Projectile:ChangeMaxZigZag(value)` to change the zig zag frequency. +---@return number +function Projectile:GetZigZagFrequency() +end + +--- Returns the zig zag distance. +--- +--- You can use `Projectile:ChangeMaxZigZag(value)` to change the zig zag distance. +---@return number +function Projectile:GetMaxZigZag() +end + --- Returns the entity that is responsible for creating this projectile. ---@return Entity | Unit | nil function Projectile:GetLauncher() @@ -118,6 +143,12 @@ end function Projectile:SetNewTargetGround(location) end +---@param x number +---@param y number +---@param z number +function Projectile:SetNewTargetGroundXYZ(x, y, z) +end + --- ---@param svx number ---@param svy number diff --git a/lua/sim/Projectile.lua b/lua/sim/Projectile.lua index 9eacc3e378..95fdb2f393 100644 --- a/lua/sim/Projectile.lua +++ b/lua/sim/Projectile.lua @@ -5,15 +5,46 @@ -- Copyright © 2005 Gas Powered Games, Inc. All rights reserved. ------------------------------------------------------------------ -local ProjectileMethods = moho.projectile_methods local DefaultDamage = import("/lua/sim/defaultdamage.lua") local Flare = import("/lua/defaultantiprojectile.lua").Flare local DepthCharge = import("/lua/defaultantiprojectile.lua").DepthCharge +-- upvalue scope for performance +local unpack = unpack +local Damage = Damage +local Random = Random +local IsAlly = IsAlly +local ForkThread = ForkThread +local DamageArea = DamageArea +local IsDestroyed = IsDestroyed +local CreateSplat = CreateSplat +local CreateEmitterAtBone = CreateEmitterAtBone +local CreateEmitterAtEntity = CreateEmitterAtEntity +local EntityCategoryContains = EntityCategoryContains + +local ProjectileMethods = moho.projectile_methods +local ProjectileMethodsCreateChildProjectile = ProjectileMethods.CreateChildProjectile +local ProjectileMethodsGetMaxZigZag = ProjectileMethods.GetMaxZigZag +local ProjectileMethodsGetZigZagFrequency = ProjectileMethods.GetZigZagFrequency + +local EntityMethods = _G.moho.entity_methods +local EntityGetBlueprint = EntityMethods.GetBlueprint +local EntityGetArmy = EntityMethods.GetArmy +local EntitySetMaxHealth = EntityMethods.SetMaxHealth +local EntitySetHealth = EntityMethods.SetHealth +local EntityGetPositionXYZ = EntityMethods.GetPositionXYZ +local EntityDestroy = EntityMethods.Destroy +local EntityGetOrientation = EntityMethods.GetOrientation + +local TrashBag = TrashBag +local TrashBagAdd = TrashBag.Add +local TrashBagDestroy = TrashBag.Destroy + +local TableEmpty = table.empty local TableGetn = table.getn -local MathCos = math.cos -local MathSin = math.sin +-- cache categories computations +local OnImpactDestroyCategories = categories.ANTIMISSILE * categories.ALLPROJECTILES -- scorch mark interaction local ScorchSplatTextures = { @@ -49,31 +80,6 @@ local OnImpactPreviousZ = 0 local VectorCached = Vector(0, 0, 0) --- upvalue for performance -local EntityGetBlueprint = _G.moho.entity_methods.GetBlueprint -local EntityGetArmy = _G.moho.entity_methods.GetArmy -local EntitySetMaxHealth = _G.moho.entity_methods.SetMaxHealth -local EntitySetHealth = _G.moho.entity_methods.SetHealth -local EntityGetPositionXYZ = _G.moho.entity_methods.GetPositionXYZ -local EntityDestroy = _G.moho.entity_methods.Destroy - -local TrashBag = TrashBag - -local TableEmpty = table.empty - -local EntityCategoryContains = EntityCategoryContains -local CreateEmitterAtBone = CreateEmitterAtBone -local CreateEmitterAtEntity = CreateEmitterAtEntity -local CreateSplat = CreateSplat -local DamageArea = DamageArea -local Damage = Damage -local Random = Random -local IsAlly = IsAlly -local ForkThread = ForkThread - --- cache categories computations -local OnImpactDestroyCategories = categories.ANTIMISSILE * categories.ALLPROJECTILES - ---@class Projectile : moho.projectile_methods, InternalObject ---@field Blueprint ProjectileBlueprint ---@field Army number @@ -122,12 +128,13 @@ Projectile = ClassProjectile(ProjectileMethods) { ---@param self Projectile The projectile that we're creating ---@param inWater? boolean Flag to indicate the projectile is in water or not OnCreate = function(self, inWater) - local blueprint = self:GetBlueprint() --[[@as ProjectileBlueprint]] + local blueprint = EntityGetBlueprint(self) --[[@as ProjectileBlueprint]] + local trash = TrashBag() --[[@as TrashBag]] self.Blueprint = blueprint - self.Army = self:GetArmy() --[[@as number]] + self.Trash = trash + self.Army = EntityGetArmy(self) --[[@as number]] self.Launcher = self:GetLauncher() --[[@as Unit]] - self.Trash = TrashBag() --[[@as TrashBag]] -- set some health, if we have some local maxHealth = blueprint.Defense.MaxHealth @@ -138,7 +145,7 @@ Projectile = ClassProjectile(ProjectileMethods) { -- do not track target, but track where the target was if blueprint.Physics.TrackTargetGround then - self.Trash:Add(ForkThread(self.OnTrackTargetGround, self)) + TrashBagAdd(trash, ForkThread(self.OnTrackTargetGround, self)) end end, @@ -169,45 +176,37 @@ Projectile = ClassProjectile(ProjectileMethods) { sz = sz + offset local dx = sx * (Random() - 0.5) * fuzziness - local dy = (sy + offset) * (Random() - 0.5) * fuzziness + sy/2 + cy + local dy = (sy + offset) * (Random() - 0.5) * fuzziness + sy / 2 + cy local dz = sz * (Random() - 0.5) * fuzziness + cz local dw -- Rotate a vector by a quaternion: q * v * conjugate(q) -- Supreme Commander quaternions use y,z,x,w! - local ty, tz, tx, tw = unpack(target:GetOrientation()) + local ty, tz, tx, tw = unpack(EntityGetOrientation(target)) -- compute the product in a single assignment to not have to use temporary, single-use variables. - dw, dx, dy, dz = - -tx * dx - tz * dy - ty * dz, - tw * dx + tz * dz - ty * dy, - tw * dy + ty * dx - tx * dz, - tw * dz + tx * dy - tz * dx + dw, dx, dy, dz = -tx * dx - tz * dy - ty * dz, + tw * dx + tz * dz - ty * dy, + tw * dy + ty * dx - tx * dz, + tw * dz + tx * dy - tz * dx tx, tz, ty = -tx, -tz, -ty - + -- compute the product in a single assignment to not have to use temporary, single-use variables. - dx, dy, dz = - dw * tx + dx * tw + dy * ty - dz * tz, - dw * tz + dy * tw + dz * tx - dx * ty, - dw * ty + dz * tw + dx * tz - dy * tx + dx, dy, dz = dw * tx + dx * tw + dy * ty - dz * tz, + dw * tz + dy * tw + dz * tx - dx * ty, + dw * ty + dz * tw + dx * tz - dy * tx - local pos = { px + dx, py + dy, pz + dz } - self:SetNewTargetGround(pos) + self:SetNewTargetGroundXYZ(px + dx, py + dy, pz + dz) else - local pos = self:GetCurrentTargetPosition() + local px, _, pz = self:GetCurrentTargetPositionXYZ() local physics = self.Blueprint.Physics local fuzziness = physics.TrackTargetGroundFuzziness or 0.8 local offset = physics.TrackTargetGroundOffset or 0 - local dx = (Random() - 0.5) * fuzziness * (1 + offset) - local dz = (Random() - 0.5) * fuzziness * (1 + offset) - - pos[1] = pos[1] + dx - pos[3] = pos[3] + dz - - pos[2] = GetSurfaceHeight(pos[1], pos[3]) - self:SetNewTargetGround(pos) + local tx = px + (Random() - 0.5) * fuzziness * (1 + offset) + local tz = pz + (Random() - 0.5) * fuzziness * (1 + offset) + self:SetNewTargetGroundXYZ(tx, GetSurfaceHeight(tx, tz), tz) end end, @@ -298,7 +297,7 @@ Projectile = ClassProjectile(ProjectileMethods) { OnDestroy = function(self) local trash = self.Trash if trash then - trash:Destroy() + TrashBagDestroy(trash) end end, @@ -571,7 +570,7 @@ Projectile = ClassProjectile(ProjectileMethods) { local trackTarget = bp.TrackTarget local trackTargetGround = bp.TrackTargetGround if trackTarget and (not trackTargetGround) then - self.Trash:Add(ForkThread(self.RetargetThread, self)) + TrashBagAdd(self.Trash, ForkThread(self.RetargetThread, self)) end end, @@ -935,7 +934,44 @@ Projectile = ClassProjectile(ProjectileMethods) { end end, - -- Deprecated functionality + --------------------------------------------------------------------------- + --#region C hooks + + --- Creates a child projectile that inherits the speed, orientation and launcher of its parent + ---@param blueprint BlueprintId + ---@return Projectile + CreateChildProjectile = function(self, blueprint) + local childProjectile = ProjectileMethodsCreateChildProjectile(self, blueprint) + childProjectile.Launcher = self.Launcher + return childProjectile + end, + + --- Returns the zig zag distance of the projectile. + ---@param self Projectile + ---@return number + GetMaxZigZag = function(self) + local distance = ProjectileMethodsGetMaxZigZag(self) + if distance == -1 then + distance = self.Blueprint.Physics.MaxZigZag or 0 + end + + return distance + end, + + --- Returns the zig zag frequency of the projectile. + ---@param self Projectile + ---@return number + GetZigZagFrequency = function(self) + local frequency = ProjectileMethodsGetZigZagFrequency(self) + if frequency == -1 then + frequency = self.Blueprint.Physics.ZigZagFrequency or 0 + end + + return frequency + end, + + --------------------------------------------------------------------------- + --#region Deprecated functionality ---@deprecated ---@param self Projectile @@ -991,18 +1027,6 @@ Projectile = ClassProjectile(ProjectileMethods) { return nil end end, - - --------------------------------------------------------------------------- - --#region C hooks - - --- Creates a child projectile that inherits the speed, orientation and launcher of its parent - ---@param blueprint BlueprintId - ---@return Projectile - CreateChildProjectile = function(self, blueprint) - local projectile = ProjectileMethods.CreateChildProjectile(self, blueprint) - projectile.Launcher = self.Launcher - return projectile - end, } --- A dummy projectile that solely inherits what it needs. Useful for