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.

Tykvesh

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!

Link to comment
Share on other sites

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 :)

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

  • 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

 

Link to comment
Share on other sites

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

 

Link to comment
Share on other sites