TBL to Strings, Oh my!
-
I'm going around in circles trying to get a units mesh from blue print and then apply to another entity. In this case I'm using a projectile to simulate part of a unit by applying the mesh to it, then hiding the unneeded bones.
Typically most units mesh's appear like so from the blue print...
Display= { Mesh = { IconFadeInZoom = 130, LODs = { { AlbedoName = 'MyUnit01_Albedo.dds', LODCutoff = 100, LookupName = '/effects/entities/PhaseShield/PhaseShieldLookup.dds', MeshName = '/mods/haha/units/MyUnit01/MyUnit01_lod0.scm', NormalsName = '/mods/haha/units/MyUnit01/MyUnit01_normalsTS.dds', Scrolling = true, ShaderName = 'PhaseShield', SpecularName = '/mods/haha/units/MyUnit01/MyUnit01_SpecTeam.dds', }, { AlbedoName = '/mods/haha/units/MyUnit01/MyUnit01_Albedo.dds', LODCutoff = 215, LookupName = '/effects/entities/PhaseShield/PhaseShieldLookup.dds', MeshName = '/mods/haha/units/MyUnit01/MyUnit01_lod1.scm', NormalsName = '/mods/haha/units/MyUnit01/MyUnit01_normalsTS.dds', ShaderName = 'PhaseShield', SpecularName = '/mods/haha/units/MyUnit01/MyUnit01_SpecTeam.dds', }, }, }, }
So later on I try using...
local stringMesh = table.concat(bp.Display.Mesh.LODs) WARN('stringMesh = '..repr(stringMesh)) proj:SetMesh(stringMesh)
And see " bad argument #1 to `concat' (table contains non-strings)"
Am i just misusing the concat or is there a better way of doing this?
Edit: SetMesh requires a string, not a table. Which is strange cause the whole game is setup as a bunch of tables.
-
Ok so progress, however slow is still progress...
Managed to use the following to change one units model to that of another unit.
local bp = self:GetBlueprint() local meshId = bp.Display.MeshBlueprint WARN('meshId: '..repr(meshId))
Though getting this to apply to a projectile is proving to be rather difficult.
proj:SetMesh(meshId)
While there are no errors shown, the projectile isn't showing either, nor can I apply a SetScale to it without it freaking out with Lua errors. Maybe I'll change to another projectile as there could be hidden Lua changing the outcome I'm after.
-
@resin_smoker
I have used the SetMesh Function on one of my UEF Aircraft Carriers in CSK Units to add some Decorations on it.
You need to Create an small Blueprint File for the SetMesh Function.MeshBlueprint { LODs = { { MeshName = '/units/uea0102/uea0102_lod0.scm', ShaderName = 'Unit', AlbedoName = '/units/uea0102/uea0102_Albedo.dds', NormalsName = '/units/uea0102/uea0102_Normals.dds', SpecularName = '/units/uea0102/uea0102_Specteam.dds', LODCutoff = 300, }, }, SortOrder = 999, }
This needs to be added to the Unit_Script.lua Code:
self.Plane01 = import('/lua/sim/Entity.lua').Entity() PlaneMesh1 = '/mods/Commander Survival Kit Units/Decorations/Plane02_mesh', self.Plane01:AttachBoneTo( -1, self, 'AttachPoint01' ) self.Plane01:SetMesh(PlaneMesh1) self.Plane01:SetDrawScale(0.060) self.Plane01:SetVizToAllies('Intel') self.Plane01:SetVizToNeutrals('Intel') self.Plane01:SetVizToEnemies('Intel')
The Result is this:
Do you See the Models of some UEF Air Units on the Aircraft Carrier?
These are the Decorations. -
@cdrmv Setting up an external file and directing a path to it is badicly how personal shields get added. What I'm after is the local ability to pull a unit mesh, modify it (example: change a shader) then apply it to another entity on the fly.
The key is being able to take the mesh table and convert it to a string. Far as I know of, SetMesh only works with strings, not tables.
-
@resin_smoker
That is actually what I want to try Out as Well.
But for an single Unit in Detail.
For example a Unit which charges Up an Weapon and some Model Parts start to glow. And If the Unit has Fire the Weapon it Switch Back to the Default Model/Shader.
Would be nice but its difficult to Release.These are a few Examples how the SetMesh Function is used by the Game on GitHub from FAF
StartBeingBuiltEffects = function(self, builder, layer) local BuildMeshBp = self.Blueprint.Display.BuildMeshBlueprint if BuildMeshBp then self:SetMesh(BuildMeshBp, true) end end, StopBeingBuiltEffects = function(self, builder, layer) local bp = self.Blueprint.Display local useTerrainType = false if bp then if bp.TerrainMeshes then local bpTM = bp.TerrainMeshes local pos = self:GetPosition() local terrainType = GetTerrainType(pos[1], pos[3]) if bpTM[terrainType.Style] then self:SetMesh(bpTM[terrainType.Style], true) useTerrainType = true end end if not useTerrainType then self:SetMesh(bp.MeshBlueprint, true) end end self.OnBeingBuiltEffectsBag:Destroy() end,
These are the two Default Calls of the SetMesh Function, which I have Seen several times.
However BuildMeshBP and MeshBlueprint is Not really clear to me where this is Declared. Both doesn't Show Up in an Blueprint File of an Unit.self:SetMesh(BuildMeshBp, true) self:SetMesh(bp.MeshBlueprint, true)
-
@cdrmv Problem comes done to the SetMesh requiring a string that points to the new mesh (table) your wanting to use.
Only two proven methods of making this work is to manually create a mesh blueprint for each unit your you intend or could possible want to change.
or
Abuse Blueprint.lua so that when it compiles all of the units (at startup) it makes extra Blueprints for the unit variations that could be possible. DMS does this, though its not compatible with FAF, so I'm looking for alternatives.
-
MeshBlueprint is seen in MohoData\system\Blueprints.lua line 149, under the following function:
function ExtractMeshBlueprint(bp) local disp = bp.Display or {} bp.Display = disp if disp.MeshBlueprint=='' then LOG('Warning: ',bp.Source,': MeshBlueprint should not be an empty string') disp.MeshBlueprint = nil end if type(disp.MeshBlueprint)=='string' then if disp.MeshBlueprint!=lower(disp.MeshBlueprint) then #Should we allow mixed-case blueprint names? #LOG('Warning: ',bp.Source,' (MeshBlueprint): ','Blueprint IDs must be all lowercase') disp.MeshBlueprint = lower(disp.MeshBlueprint) end # strip trailing .bp disp.MeshBlueprint = gsub(disp.MeshBlueprint, "%.bp$", "") if disp.Mesh then LOG('Warning: ',bp.Source,' has mesh defined both inline and by reference') end end if disp.MeshBlueprint==nil then # For a blueprint file "/units/uel0001/uel0001_unit.bp", the default # mesh blueprint is "/units/uel0001/uel0001_mesh" local meshname,subcount = gsub(bp.Source, "_[a-z]+%.bp$", "_mesh") if subcount==1 then disp.MeshBlueprint = meshname end if type(disp.Mesh)=='table' then local meshbp = disp.Mesh meshbp.Source = meshbp.Source or bp.Source meshbp.BlueprintId = disp.MeshBlueprint # roates: Commented out so the info would stay in the unit BP and I could use it to precache by unit. # disp.Mesh = nil MeshBlueprint(meshbp) end end end
BuildMeshBP is seen in MohoData\system\Blueprints.lua line 223, under the following function:
function ExtractBuildMeshBlueprint(bp) local FactionName = bp.General.FactionName if FactionName == 'Aeon' or FactionName == 'UEF' or FactionName == 'Cybran' or FactionName == 'Seraphim' then local meshid = bp.Display.MeshBlueprint if not meshid then return end local meshbp = original_blueprints.Mesh[meshid] if not meshbp then return end local shadername = FactionName .. 'Build' local secondaryname = '/textures/effects/' .. FactionName .. 'BuildSpecular.dds' local buildmeshbp = table.deepcopy(meshbp) if buildmeshbp.LODs then for i,lod in buildmeshbp.LODs do lod.ShaderName = shadername lod.SecondaryName = secondaryname if FactionName == 'Seraphim' then lod.LookupName = '/textures/environment/Falloff_seraphim_lookup.dds' end end end buildmeshbp.BlueprintId = meshid .. '_build' bp.Display.BuildMeshBlueprint = buildmeshbp.BlueprintId MeshBlueprint(buildmeshbp) end end
It looks like ExtractBuildMeshBlueprint is applying BuildSpecular for when a unit is being constructed at a factory. This could indicate a way to create your own custom blueprints during the game load-up. Then later be able to reference them and call them up as needed.
Further up Blueprint.lua check out the following function:
function ExtractAllMeshBlueprints() for id,bp in original_blueprints.Unit do ExtractMeshBlueprint(bp) ExtractWreckageBlueprint(bp) ExtractBuildMeshBlueprint(bp) end for id,bp in original_blueprints.Prop do ExtractMeshBlueprint(bp) ExtractWreckageBlueprint(bp) end for id,bp in original_blueprints.Projectile do ExtractMeshBlueprint(bp) end end
This appears to kick off each of the Mesh build-ups in sequence. Could simply create your own function via /hook then reference it here towards the end of the file. Far as I can tell, doing so wouldn't change the game or how it behaves as your just adding in your own Mesh variants that are being saved as a global.
Please note: I pulled the above snippets from vanilla FA as not all files are always represented in the FAF Client. In this case, I've confirmed that FAF client does not have a Blueprint.lua as it's using the original vanilla version.
Resin
-
DMS uses a custom Blueprint.lua via /hook that looks very promising. Goto line 384 to see DMS_ExtractPersonalShieldMeshBlueprint.
Edit: Just added it to 4DFAF and it appears to run correctly.
INFO: Hooked /lua/system/Blueprints.lua with /mods/4dfaf/hook/lua/system/Blueprints.lua INFO: Blueprints Loading... '*.bp' files INFO: Blueprints Loading: original files from /effects directory INFO: Blueprints Loading: original files from /env directory INFO: Blueprints Loading: original files from /meshes directory INFO: Blueprints Loading: original files from /projectiles directory INFO: Blueprints Loading: original files from /props directory INFO: Blueprints Loading: original files from /units directory INFO: Blueprints Loading: modded files from "4D-FAF (4th-Dimension for FAF) v2, UEF Units" mod INFO: Blueprints Extracting mesh... INFO: Blueprints Modding... INFO: Blueprints Loading... completed: 604 original, 18 modded, and 74 preset units INFO: Blueprints Loading... completed: 392 original and 11 modded projectiles INFO: Blueprints Registering...
-
OMG! Just did a quick WARN('Self blueprint: '..repr(self:GetBlueprint())) on one of my units and saw this for the units Display / Mesh section:
WARNING: - Display: table: 1B5AF7A8 WARNING: - Abilities: table: 1B5AF4B0 WARNING: - 1: Transforming WARNING: - 2: 35% Phasing in Air Mode WARNING: - 3: Shield Piercing Missile WARNING: - 4: Chain Lightning WARNING: - AnimationDeath: table: 1B5AF528 WARNING: - 1: table: 1B5AF550 WARNING: - Animation: /mods/4DFAF/units/xsl0310/xsl0310_Death01.sca WARNING: - AnimationRateMax: 1.75 WARNING: - AnimationRateMin: 1.1499999761581 WARNING: - Weight: 50 WARNING: - 2: table: 1B5AF578 WARNING: - Animation: /mods/4DFAF/units/xsl0310/xsl0310_death02.sca WARNING: - AnimationRateMax: 1.75 WARNING: - AnimationRateMin: 1.1499999761581 WARNING: - Weight: 33 WARNING: - AnimationWalk: /mods/4DFAF/units/xsl0310/xsl0310_Awalk.sca WARNING: - AnimationWalkRate: 0.64399999380112 WARNING: - BuildMeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh_build WARNING: - CloakMeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh_cloak WARNING: - DisplayName: WARNING: - HideLifebars: false WARNING: - IconName: xsl0310 WARNING: - Mesh: table: 1B5AF438 WARNING: - BlueprintId: /mods/4dfaf/units/xsl0310/xsl0310_mesh WARNING: - BlueprintOrdinal: 1297 WARNING: - Description: WARNING: - IconFadeInZoom: 130 WARNING: - LODs: table: 1B5AF460 WARNING: - 1: table: 1B5AF488 WARNING: - AlbedoName: /mods/4dfaf/units/xsl0310/xsl0310_albedo.dds WARNING: - LODCutoff: 225.20259094238 WARNING: - LookupName: /textures/environment/Falloff_seraphim_lookup.dds WARNING: - MeshName: /mods/4dfaf/units/xsl0310/xsl0310_lod0.scm WARNING: - NormalsName: /mods/4dfaf/units/xsl0310/xsl0310_normalsTS.dds WARNING: - Occlude: false WARNING: - Scrolling: true WARNING: - SecondaryName: WARNING: - ShaderName: Seraphim WARNING: - Silhouette: false WARNING: - SpecularName: /mods/4dfaf/units/xsl0310/xsl0310_SpecTeam.dds WARNING: - SortOrder: 0 WARNING: - Source: /mods/4dfaf/units/xsl0310/xsl0310_unit.bp WARNING: - StraddleWater: false WARNING: - UniformScale: 1 WARNING: - MeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh WARNING: - MeshBlueprintWrecked: /mods/4dfaf/units/xsl0310/xsl0310_mesh_wreck WARNING: - MovementEffects: table: 1B5AF7D0 WARNING: - Land: table: 1B5AF7F8 WARNING: - Effects: table: 1B5AF320 WARNING: - 1: table: 1B5AF348 WARNING: - Bones: table: 1B5AF370 WARNING: - 1: LeftExhaust WARNING: - 2: RightExhaust WARNING: - Offset: table: 1B5AF3C0 WARNING: - 1: 0 WARNING: - 2: -0.40000000596046 WARNING: - 3: 0 WARNING: - Type: GroundKickup01 WARNING: - PersonalShieldMeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh_personalshield
BuildMeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh_build
CloakMeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh_cloak
MeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh
MeshBlueprintWrecked: /mods/4dfaf/units/xsl0310/xsl0310_mesh_wreck
PersonalShieldMeshBlueprint: /mods/4dfaf/units/xsl0310/xsl0310_mesh_personalshield
Domino is the F'n man!
-
YES !!!! I got the shield drone to work !
Video link (If it first doesn't work, then YouTube may still be processing it): https://youtu.be/IV39URap11s
-
Added a copy of this unit to the FAF server unit the name "4D-FAF (4th-Dimension for FAF), UEF & Seraphim Units".