Need help with underwater wreck spawning code

Everything about mods can be found here.

Moderator: Morax

Need help with underwater wreck spawning code

Postby utterbob » 29 Sep 2013, 11:26

I am trying to re-create the sinking wrecks in FA3599 as a project to learn both the functions (and thus the possibilities for something of my own) and a bit more about hooking.

I can get the hover units to sink but they just vanish through the seafloor and don't create a wreck, could really use some guidance from someone with a better understanding than me!

I'm reasonably certain the problem is somewhere in;
Code: Select all
   function CreateWreckageProp( self, overkillRatio )
      local bp = self:GetBlueprint()
      local wreck = bp.Wreckage.Blueprint
      local pos = self:GetPosition()
      local mass = bp.Economy.BuildCostMass * (bp.Wreckage.MassMult or 0)
      local energy = bp.Economy.BuildCostEnergy * (bp.Wreckage.EnergyMult or 0)
      local time = (bp.Wreckage.ReclaimTimeMultiplier or 1)

      --pos[2] = GetTerrainHeight(pos[1], pos[3]) + GetTerrainTypeOffset(pos[1], pos[3])

      local prop = CreateProp( pos, wreck )

      prop:SetScale(bp.Display.UniformScale)
      prop:SetOrientation(self:GetOrientation(), true)
      prop:SetPropCollision('Box', bp.CollisionOffsetX, bp.CollisionOffsetY, bp.CollisionOffsetZ, bp.SizeX* 0.5, bp.SizeY* 0.5, bp.SizeZ * 0.5)
      prop:SetMaxReclaimValues(time, time, mass, energy)

      mass = (mass - (mass * (overkillRatio or 1))) * self:GetFractionComplete()
      energy = (energy - (energy * (overkillRatio or 1))) * self:GetFractionComplete()
      time = time - (time * (overkillRatio or 1))

      prop:SetReclaimValues(time, time, mass, energy)
      prop:SetMaxHealth(bp.Defense.Health)
      prop:SetHealth(self, bp.Defense.Health * (bp.Wreckage.HealthMult or 1))

        if not bp.Wreckage.UseCustomMesh then
           prop:SetMesh(bp.Display.MeshBlueprintWrecked)
        end

        TryCopyPose(self,prop,false)

        prop.AssociatedBP = self:GetBlueprint().BlueprintId

      return prop
    end

Pretty sure I have the hooking right, since they sink, but here is the whole thing...
Disclaimer: A lot of this is copied code, credit goes to the original authors
Code: Select all
local Unit = import('sim/unit.lua').Unit

local Shield = import('shield.lua').Shield

local explosion = import('defaultexplosions.lua')

local Util = import('utilities.lua')
local
EffectUtil = import('EffectUtilities.lua')

local EffectTemplate = import('EffectTemplates.lua')

local ScenarioUtils = import('/lua/sim/ScenarioUtilities.lua')

local EffectUtil = import('EffectUtilities.lua')

local CreateBuildCubeThread = EffectUtil.CreateBuildCubeThread

local CreateAeonBuildBaseThread = EffectUtil.CreateAeonBuildBaseThread

local Entity = import('sim/entity.lua').Entity


local OldSeaUnit = SeaUnit


local function CreateScaledBoom(unit, overkill, bone)
   
explosion.CreateDefaultHitExplosionAtBone(
      unit,
      bone or 0,
explosion.CreateUnitExplosionEntity(unit, overkill).Spec.BoundingXZRadius
   )
end

**Naval units class hooks here (SeaUnit & SubUnit) - both work**

local OldHoverLandUnit = HoverLandUnit

HoverLandUnit = startClass(OldHoverLandUnit)

DeathThread = function(self, overkillRatio, instigator)

               
                if self:GetCurrentLayer() == 'Water' then
                        CreateScaledBoom(self, overkillRatio)
                        local sx, sy, sz = self:GetUnitSizes()
                        local vol = sx * sy * sz
                        local army = self:GetArmy()
                        local pos = self:GetPosition()
                        local seafloor = GetTerrainHeight(pos[1], pos[3]) + GetTerrainTypeOffset(pos[1], pos[3])
                        local DaveyJones = (seafloor - pos[2])*20
                        local numBones = self:GetBoneCount()-1
               
               
                        self:ForkThread(function()
                                ##LOG("Sinker thread created")
                                local pos = self:GetPosition()
                                local seafloor = GetTerrainHeight(pos[1], pos[3]) + GetTerrainTypeOffset(pos[1], pos[3])
                                while self:GetPosition(1)[2] > (seafloor) do  #added 2 because they were sinking into the seafloor
                                        WaitSeconds(0.1)
                                        ##LOG("Sinker: ", repr(self:GetPosition()))
                                end
                                CreateScaledBoom(self, overkillRatio, watchBone)
                                self:CreateWreckage(overkillRatio, instigator)
                                self:Destroy()
                        end)
               
               
                        self:ForkThread(function()
                                local i = 0
                                while true do
                                        local rx, ry, rz = self:GetRandomOffset(0.25)
                                        local rs = Random(vol/2, vol*2) / (vol*2)
                                        local randBone = Util.GetRandomInt( 0, numBones)

                                        CreateEmitterAtBone( self, randBone, army, '/effects/emitters/destruction_underwater_explosion_flash_01_emit.bp')
                                                :ScaleEmitter(sx)
                                                :OffsetEmitter(rx, ry, rz)
                                        CreateEmitterAtBone( self, randBone, army, '/effects/emitters/destruction_underwater_sinking_wash_01_emit.bp')
                                                :ScaleEmitter(sx/2)
                                                :OffsetEmitter(rx, ry, rz)

                                       
                                        local rd = Util.GetRandomFloat( 0.4+i, 1.0+i)
                                        WaitSeconds(rd)
                                        i = i + 0.3
                                end
                        end)
               
                        #what does this even do I have no idea
                        local slider = CreateSlider(self, 0)
                        slider:SetGoal(0, DaveyJones+10, 0)  #changed from +5 to +10
                        slider:SetSpeed(8)
                        WaitFor(slider)
                        slider:Destroy()
                       
                        CreateScaledBoom(self, overkillRatio)
                        self:CreateWreckage(overkillRatio, instigator)
                        self:Destroy()
                        else
                                MobileUnit.DeathThread(self, overkillRatio, instigator)
                        end
                               
        end

   function CreateWreckageProp( self, overkillRatio )
      local bp = self:GetBlueprint()
      local wreck = bp.Wreckage.Blueprint
      local pos = self:GetPosition()
      local mass = bp.Economy.BuildCostMass * (bp.Wreckage.MassMult or 0)
      local energy = bp.Economy.BuildCostEnergy * (bp.Wreckage.EnergyMult or 0)
      local time = (bp.Wreckage.ReclaimTimeMultiplier or 1)

      --pos[2] = GetTerrainHeight(pos[1], pos[3]) + GetTerrainTypeOffset(pos[1], pos[3])

      local prop = CreateProp( pos, wreck )

      prop:SetScale(bp.Display.UniformScale)
      prop:SetOrientation(self:GetOrientation(), true)
      prop:SetPropCollision('Box', bp.CollisionOffsetX, bp.CollisionOffsetY, bp.CollisionOffsetZ, bp.SizeX* 0.5, bp.SizeY* 0.5, bp.SizeZ * 0.5)
      prop:SetMaxReclaimValues(time, time, mass, energy)

      mass = (mass - (mass * (overkillRatio or 1))) * self:GetFractionComplete()
      energy = (energy - (energy * (overkillRatio or 1))) * self:GetFractionComplete()
      time = time - (time * (overkillRatio or 1))

      prop:SetReclaimValues(time, time, mass, energy)
      prop:SetMaxHealth(bp.Defense.Health)
      prop:SetHealth(self, bp.Defense.Health * (bp.Wreckage.HealthMult or 1))

        if not bp.Wreckage.UseCustomMesh then
           prop:SetMesh(bp.Display.MeshBlueprintWrecked)
        end

        TryCopyPose(self,prop,false)

        prop.AssociatedBP = self:GetBlueprint().BlueprintId

      return prop
    end
endClass()


EDIT: P.S. The UEF shield boat & Atlantis don't leave visible wrecks but they are still reclaimable (haven't checked other factions). I thought it might be due to them having wreckage info that was returning empty (or no) wreckage .dds but neither these, nor the ships that work, have any wreckage data in the bp. Anyone know how to fix this too?
utterbob
 
Posts: 7
Joined: 23 Sep 2013, 17:32
Has liked: 0 time
Been liked: 0 time
FAF User Name: UtterBob

Re: Need help with underwater wreck spawning code

Postby utterbob » 02 Oct 2013, 14:32

Well the main question turned out to be a syntax error. I had checked it so many times I lost count but when I re-did it from the ground up it was fine.

Now I have 2 curious problems...

EDIT: Solved this one, turned out the variable I ruled out was the problem, have to assume something at the engine level is handling different unit types differently with GetPosition().
Spoiler: show
Firstly, all hover units (including engineers) sink normally and wreck on the seafloor in shallow water but sink through the seafloor in deeper water... the deeper the water the further through the seafloor they go. I thought this was a multiplier in the height calculations but the only one there is also in the ship and sub code and those work fine!


Second problem is that some specific units are not behaving like the rest of their class. Only tested UEF extensively on this (so far) but the T3 Battleship, T2 shield boat and Atlantis all suffer from sinking though the seafloor and vanishing but still being reclaimable (consistent at any water depth). I can't find any unique features that would logically separate these 3 out in terms of death functions.

Any help on those 2 problems would be greatly appreciated!
utterbob
 
Posts: 7
Joined: 23 Sep 2013, 17:32
Has liked: 0 time
Been liked: 0 time
FAF User Name: UtterBob

Re: Need help with underwater wreck spawning code

Postby dstojkov » 24 Oct 2013, 23:03

take a look to my FA UNLEASHED mod

I made my own water wreck stuff that I personally find better that the faf's implementation. The mod is not in a working state right now nevertheless you can still find in the hook folder my own implementation.

Regards
dstojkov
Evaluator
 
Posts: 775
Joined: 21 Sep 2011, 22:04
Has liked: 0 time
Been liked: 24 times


Return to Mods & Tools

Who is online

Users browsing this forum: No registered users and 1 guest