Skip to content

Commit

Permalink
Fix wrecks of sinking units ending up below the terrain (FAForever#5897)
Browse files Browse the repository at this point in the history
  • Loading branch information
Garanas authored Feb 11, 2024
1 parent 5dd16c0 commit 7cedaf1
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 14 deletions.
1 change: 1 addition & 0 deletions engine/Core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
41 changes: 30 additions & 11 deletions lua/ScenarioFramework.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions lua/sim/Unit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lua/wreckage.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 7cedaf1

Please sign in to comment.