Jump to content

Add HasBloomEffectHandle function for AnimState


Recommended Posts

Currently there is no way to tell (from the code) if an entity has a BloomEffectHandle or not.

Considering this wasn't included in the first place, it makes me think that there are some limitations preventing such possibility?

local inst = SpawnPrefab("goldnugget")
print(inst.AnimState:GetBloomEffectHandle()) --result: "shaders/anim.ksh"

local inst = SpawnPrefab("axe")
print(inst.AnimState:GetBloomEffectHandle()) --result: nil

It'd be nice to at least have a function that just returns true or false. If even this version is not possible, may I know why?

local inst = SpawnPrefab("goldnugget")
print(inst.AnimState:HasBloomEffectHandle()) --result: true

local inst = SpawnPrefab("axe")
print(inst.AnimState:HasBloomEffectHandle()) --result: false

Thanks!

3 hours ago, Tykvesh said:

Currently there is no way to tell (from the code) if an entity has a BloomEffectHandle or not.

This would be great! I remember needing a function like this some time ago in DST but of course it wasnt implemented sadly :(

Spoiler

I did find an alternative solution though! You might want to use it so here you go.


local _SetBloomEffectHandle = getmetatable(inst.AnimState).__index["SetBloomEffectHandle"]
getmetatable(inst.AnimState).__index["SetBloomEffectHandle"] = function(self, bloom, ...)
        _SetBloomEffectHandle(self, bloom, ...)
        
        if bloom ~= nil then
                inst.has_bloom = true
        else
                inst.has_bloom = false
        end
end

getmetatable(inst.AnimState).__index["HasBloomEffectHandle"] = function(self)
        return inst.has_bloom or false
end

You can put this code into a PrefabPostinit for whatever prefab of your choice and a HasBloomEffectHandle function will be defined that you can then use :)

 

4 minutes ago, Hornete said:

You can put this code into a PrefabPostinit for whatever prefab of your choice and a HasBloomEffectHandle function will be defined that you can then use :)

Sadly your solution has a serious flaw – every AnimState shares the same metatable. So if you add or override something in it, you apply that to every AnimState.

Which leads to a bottleneck:

  • Any entity that calls SetBloomEffectHandle will call it for your prefab as well
  • Every PrefabPostInit will just tackle more and more functions on top of each other

I can't say for sure, but probably any userdata is like that.

38 minutes ago, Tykvesh said:

Sadly your solution has a serious flaw – every AnimState shares the same metatable. So if you add or override something in it, you apply that to every AnimState.

Which leads to a bottleneck:

  • Any entity that calls SetBloomEffectHandle will call it for your prefab as well
  • Every PrefabPostInit will just tackle more and more functions on top of each other

I can't say for sure, but probably any userdata is like that.

Oh right. I think this should solve the first issue?

local _SetBloomEffectHandle = getmetatable(inst.AnimState).__index["SetBloomEffectHandle"]
getmetatable(inst.AnimState).__index["SetBloomEffectHandle"] = function(self, bloom, ...)
        _SetBloomEffectHandle(self, bloom, ...)
        
        if self == inst.AnimState
                if bloom ~= nil then
                      inst.has_bloom = true
               else
                      inst.has_bloom = false
               end
       end
end

getmetatable(inst.AnimState).__index["HasBloomEffectHandle"] = function(self)
        if self == inst.AnimState then
               return inst.has_bloom or false
        end
end

But yeah, it's still not so great. Hopefully we get a HasBloomEffectHandle function in a future update haha

  • Developer

You don't need to complicate it so much, this will work perfect.

local AnimStateLuaData = setmetatable({}, {__mode = "k"}) --this makes this table not keep alive references when the AnimState userdata gets garbage collected.

function AnimState:GetBloomEffectHandle()
	return AnimStateLuaData[self]
end

local _SetBloomEffectHandle = AnimState.SetBloomEffectHandle
function AnimState:SetBloomEffectHandle(bloomeffecthandle, ...)
	AnimStateLuaData[self] = bloomeffecthandle
	return _SetBloomEffectHandle(self, bloomeffecthandle, ...)
end

 

5 minutes ago, zarklord_klei said:

You don't need to complicate it so much, this will work perfect.

Haha, you outpaced me!

I was about to post this version:

local _animstateinstances = setmetatable({}, { __mode = "kv" })
local _bloomeffecthandles = setmetatable({}, { __mode = "k" })

local AddNetwork = Entity.AddNetwork
function Entity:AddNetwork(...)
	local guid = self:GetGUID()
	local inst = Ents[guid]
	if inst ~= nil and inst.AnimState ~= nil then
		_animstateinstances[inst.AnimState] = inst
		inst._hasbloomeffecthandle = net_bool(inst.GUID, "AnimState.HasBloomEffectHandle")
	end
	return AddNetwork(self, ...)
end

local function _onsetbloomeffecthandle(self)
	local inst = _animstateinstances[self]
	if inst ~= nil then
		inst._hasbloomeffecthandle:set(_bloomeffecthandles[self] ~= nil)
	end
end

local SetBloomEffectHandle = AnimState.SetBloomEffectHandle
function AnimState:SetBloomEffectHandle(bloom, ...)
	_bloomeffecthandles[self] = bloom
	_onsetbloomeffecthandle(self)
	return SetBloomEffectHandle(self, bloom, ...)			
end

local ClearBloomEffectHandle = AnimState.ClearBloomEffectHandle
function AnimState:ClearBloomEffectHandle(...)
	_bloomeffecthandles[self] = nil
	_onsetbloomeffecthandle(self)
	return ClearBloomEffectHandle(self, ...)
end

function AnimState:HasBloomEffectHandle()
	local inst = _animstateinstances[self]
	if inst ~= nil and inst.Network ~= nil and not TheWorld.ismastersim then
		return inst._hasbloomeffecthandle:value()
	else
		return _bloomeffecthandles[self] ~= nil
	end
end

--for networked entities, this is ONLY valid on mastersim!!!
function AnimState:GetBloomEffectHandle()
	return _bloomeffecthandles[self]
end

 

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...