diff --git a/engine/Core.lua b/engine/Core.lua index 3ee6ae4fb7..af6cf4161a 100644 --- a/engine/Core.lua +++ b/engine/Core.lua @@ -103,6 +103,7 @@ end --- returns true if a unit category contains this unit ---@param category EntityCategory ---@param unit Unit | UserUnit | UnitId | Projectile +---@return boolean function EntityCategoryContains(category, unit) end diff --git a/lua/ScenarioFramework.lua b/lua/ScenarioFramework.lua index 97ce6ac366..552254e724 100644 --- a/lua/ScenarioFramework.lua +++ b/lua/ScenarioFramework.lua @@ -2301,25 +2301,44 @@ function MoveOnMap(unit) end --- Returns the closest point on the map ----@param pos Vector +---@param position Vector ---@return Vector +---@return boolean function GetNearestPlayablePoint(position) + local px, _, pz = unpack(position) local playableArea = ScenarioInfo.PlayableArea - local nearestPoint = {position[1], position[2], position[3]} - if position[1] < playableArea[1] then - nearestPoint[1] = playableArea[1] + 5 - elseif position[1] > playableArea[3] then - nearestPoint[1] = playableArea[3] - 5 + -- keep track whether the point is actually outside the map + local isOutside = false + + if px < playableArea[1] then + isOutside = true + px = playableArea[1] + 5 + elseif px > playableArea[3] then + isOutside = true + px = playableArea[3] - 5 end - if position[3] < playableArea[2] then - nearestPoint[3] = playableArea[2] + 5 - elseif position[3] > playableArea[4] then - nearestPoint[3] = playableArea[4] - 5 + if pz < playableArea[2] then + isOutside = true + pz = playableArea[2] + 5 + elseif pz > playableArea[4] then + isOutside = true + pz = playableArea[4] - 5 + end + + -- if it really is outside the map then we allocate a new vector + if isOutside then + return { + px, + GetTerrainHeight(px, pz), + pz + }, true + end - return nearestPoint + -- otherwise nothing has changed, so return the existing position + return position, false end --- Returns if the unit's army is human diff --git a/lua/sim/Unit.lua b/lua/sim/Unit.lua index 5d597b9b04..b493a0b45d 100644 --- a/lua/sim/Unit.lua +++ b/lua/sim/Unit.lua @@ -1678,6 +1678,7 @@ Unit = ClassUnit(moho.unit_methods, IntelComponent, VeterancyComponent) { energy = energy * (bp.Wreckage.EnergyMult or 0) local time = (bp.Wreckage.ReclaimTimeMultiplier or 1) local pos = self:GetPosition() + local wasOutside = false local layer = self.Layer -- Reduce the mass value based on the tech tier @@ -1706,7 +1707,7 @@ Unit = ClassUnit(moho.unit_methods, IntelComponent, VeterancyComponent) { -- Create potentially offmap wrecks on-map. Exclude campaign maps that may do weird scripted things. if self.Brain.BrainType == 'Human' and (not ScenarioInfo.CampaignMode) then - pos = GetNearestPlayablePoint(pos) + pos, wasOutside = GetNearestPlayablePoint(pos) end local halfBuilt = self:GetFractionComplete() < 1 @@ -1729,7 +1730,7 @@ Unit = ClassUnit(moho.unit_methods, IntelComponent, VeterancyComponent) { -- Attempt to copy our animation pose to the prop. Only works if -- the mesh and skeletons are the same, but will not produce an error if not. if self.Tractored or (layer ~= 'Air' or (layer == "Air" and halfBuilt)) then - TryCopyPose(self, prop, false) + TryCopyPose(self, prop, not wasOutside) end -- Create some ambient wreckage smoke diff --git a/lua/wreckage.lua b/lua/wreckage.lua index 24abab9993..6b8ecb1593 100644 --- a/lua/wreckage.lua +++ b/lua/wreckage.lua @@ -109,7 +109,7 @@ Wreckage = Class(Prop) { ---@param energy number ---@param time number ---@param deathHitBox? table ----@return Prop +---@return Wreckage function CreateWreckage(bp, position, orientation, mass, energy, time, deathHitBox) local prop = CreateProp(position, bp.Wreckage.Blueprint) prop:SetOrientation(orientation, true)