zimberzimber wrote:How does one replicate the healing crystals gradual darkening on use, and how do I change the animation speed? (so it would turn darker, and spin slower like it does after you use it)
Tried attaching the models emissive color to the sounds volume level or to the lights brightness through an 'onUpdate()' function and fade them out, but it doesn't seem to work. (I can guess why)
I'm trying to replicate the 'crystal' component so I would have more control over whats happening.
Here is the closest recreation of the builtin healing_crystal+CrystalComponent shader behaviour I was able to manage:
Code: Select all
-- CrystalComponent only works properly if the material is named
-- "healing_crystal".
defineObject{
name = "g1_healing_crystal",
baseObject = "healing_crystal",
components = {
{
class = "Model",
model = "mod_assets/g1/Healing_Crystal/healing_crystal.fbx",
castShadow = false,
material = "g1_healing_crystal_42",
},
{
class = "Light",
offset = vec(0,1,0),
color = vec(39/255, 90/255, 205/255),
range = 7,
shadowMapSize = 128,
castShadow = true,
staticShadows = true,
-- lame attempt at imitating the crystalIntensity fadeout (it
-- only happens naturally for the "healing_crystal" material)
onUpdate = function(self)
local v = math.max(math.min(1,self.go.sound:getVolume()*2),0)
local choice = math.modf(v*42+0.01)
self.go.model:setMaterial(string.format("g1_healing_crystal_%d",choice))
end,
},
},
}
-- Shader params don't seem to have changed between Grimrock 1 and 2.
-- At 60 FPS, there are 43 frames between the crystal starting to fade and
-- finishing with fading.
-- Unfortunately, I don't have a good way to mimic the effect where the
-- shadeTexAngle stops changing.
for i=0,42 do
defineMaterial{
name = string.format("g1_healing_crystal_%d",i),
diffuseMap = "mod_assets/g1/Healing_Crystal/healing_crystal_dif.tga",
specularMap = "mod_assets/g1/Healing_Crystal/healing_crystal_spec.tga",
normalMap = "mod_assets/g1/Healing_Crystal/healing_crystal_normal.tga",
doubleSided = false,
lighting = true,
ambientOcclusion = false,
alphaTest = false,
blendMode = "Opaque",
textureAddressMode = "Wrap",
glossiness = 20,
depthBias = 0,
shader = "crystal",
shadeTex = "assets/textures/env/healing_crystal_shadetex.tga",
shadeTexAngle = 0,
crystalIntensity = 0.5+3.5*i/89,
onUpdate = function(self, time)
self:setParam("shadeTexAngle", time*0.8)
end,
}
end
end
Instead of switching out materials, you could instead define a different material for every individual healing crystal on a level (you can share them between levels since you can't see two objects on different levels at once), and use the onUpdate hook to dynamically change the crystalIntensity param.
Emissive color should not appear at any point during this.
Recreating the slower animation is easier. Since the healing crystal animation doesn't involve any mesh deformation, you can remove the actual animation, separate the crystal model into 5 models, and re-create the animation using Component:setOffset() and Component:setRotationAngles() every frame to move and rotate each of the 5 models the same way the animation would.