Jump to content

inst.MiniMapEntity:SetCanUseCache(False) in deerclopseyeball_sentryward.lua does not work as I expected


clearlove
  • Pending

In deerclopseyeball_sentryward.lua, line 322,


local function OnActiveDirty(inst)
    if inst._active:value() then
        local p = LIGHT_PARAMS.ON

        if TheWorld.ismastersim then
            inst.Light:Enable(true)
        end

        inst.components.lighttweener:StartTween(inst.Light, p.radius, p.intensity, p.falloff, p.colour, p.time)

        inst.AnimState:SetSymbolBloom("crystal_hand")
        inst.AnimState:SetSymbolBloom("base_crystal")

        if PostProcessor == nil or PostProcessor:IsBloomEnabled() then
            inst.AnimState:SetSymbolMultColour("crystal_hand", unpack(BLOOMED_SYMBOLS_MULTCOLOUR))
            inst.AnimState:SetSymbolMultColour("base_crystal", unpack(BLOOMED_SYMBOLS_MULTCOLOUR))
        end

        if not TheNet:IsDedicated() and inst.eyeball == nil then
            inst.eyeball = CLIENT_CreateEyeball()
            inst.eyeball.entity:SetParent(inst.entity)
            inst.highlightchildren = { inst.eyeball }
        end

        inst.MiniMapEntity:SetCanUseCache(false)
        inst.MiniMapEntity:SetDrawOverFogOfWar(true)
    else
        local p = LIGHT_PARAMS.OFF

        inst.components.lighttweener:StartTween(inst.Light, p.radius, p.intensity, p.falloff, p.colour, p.time, TurnLightOffCallback)

        inst.AnimState:ClearSymbolBloom("crystal_hand")
        inst.AnimState:ClearSymbolBloom("base_crystal")

        inst.AnimState:SetSymbolMultColour("crystal_hand", 1, 1, 1, 1)
        inst.AnimState:SetSymbolMultColour("base_crystal", 1, 1, 1, 1)

        if inst.eyeball ~= nil then
            inst.eyeball:Remove()
            inst.eyeball = nil
            inst.highlightchildren = nil
        end

        inst.MiniMapEntity:SetCanUseCache(true)
        inst.MiniMapEntity:SetDrawOverFogOfWar(false)
    end
end

`SetCanUseCache(false)` seems not working for player A if the icon is within sight of player A when called that function. I am not sure whether this is a bug of function `SetCanUseCache` itself or this is a bug caused by wrong usage.


Steps to Reproduce

1. Player A takes off the eyeball from the deerclopseyeball_sentryward and goes away.

2. player A can still see a "deerclopseyeball_sentryward_disabled.png" icon on the map, which means that the icon is still cached even though the `inst.MiniMapEntity:SetCanUseCache(False)` is called.

3. If the deerclopseyeball_sentryward is within the sight of player B, B can also see the cached icon. If not, the cached icon will be cleared in B's map.

  • Like 1



User Feedback


I'll investigate and compare with other similar cases soon, but right away something I can think off is that is that client sleep (which removes entities) does affect deerclopseyeball_sentryward, as it's not set to not sleep (or to allow sleep on clients instead of being removed). Meaning OnActiveDirty never reaches clients too far from it, as the entity is despawned.

 

The separate global icon entity doesn't sleep, so that one should always be updating the icon through the server and getting despawned for everyone at the same time, so, I'll get back to you if after some testing.

EDIT: I'm not too familiar with mini map stuff, but I guess that if an minimapentity icon is cached, and the entity is removed, the icon stays cached until revealed on the map to refresh it, meaning that if that's case, the entity needs to sleep on clients instead of getting removed (or the server needs to be able to broadcast the mini map change when the entity doesn't exist on the client somehow).

 

Also something a bit related I noticed, with the global icon entities, which might not be intended:

local function overfog_fn()
    local inst = fn()

    inst.MiniMapEntity:SetDrawOverFogOfWar(true)

    return inst
end

local function overfog_seeable_fn()
    local inst = fn()

    inst.MiniMapEntity:SetDrawOverFogOfWar(true, true)

    return inst
end

Those MiniMapEntity calls are happening outside of the pristine state, shouldn't they be called inside the fn function, prior to SetPristine (by passing them over to it)? Unless nothing gets networked out of these calls, but it'd probably be good practice to put them in the pristine state since they're engine methods.

Edited by hoxi

Share this comment


Link to comment
Share on other sites

Okay so, after trying a bunch of different things, nevermind what I said, it's not necessarily SetCanUseCache that's the issue I don't think, nor the entity being asleep (or removed on clients by client sleep), it's more that, for the disabled icon to show up for players not close to it after a player close to it disables it, the maprevealer component needs to immediately do a reveal for all players after disabling all the map reveal stuff on the server.

 

I believe the disabled icon is supposed to show up just like any other structure, if you walked near it to discover it. Problem is, when enabled and revealing the map around it, it unintentionally disappears when far away and another player disables it. This can be fixed by forcing a refresh:

local function OnEyeballTaken(inst, item, taker)
    -- rest of the function

    local revealer = inst.components.maprevealer
    for i, v in ipairs(AllPlayers) do
        revealer:RevealMapToPlayer(v)
    end
end

Not sure if that's the most ideal way but it seems to work. Basically with this change, since the icon is still supposed to be visible for players up until this point, due to it revealing the map around it, it will reveal itself with the disabled icon, caching it (since this was enabled by this point). After that, if a player close to it removes it or not, it won't change for you, just like with other structures, and you'll need to walk close to it or have another map revealing entity update it for you.

Only thing is that this will still remove the icon from the map when hammering it or so and the player isn't close, so that also needs to be accounted for. This also happens with the Ocuvigil (sentryward), it just disappears instead of becoming a cached icon.

 

Edit: oh I should clarify regarding your steps to reproduce:

Quote

1. Player A takes off the eyeball from the deerclopseyeball_sentryward and goes away.

2. player A can still see a "deerclopseyeball_sentryward_disabled.png" icon on the map, which means that the icon is still cached even though the `inst.MiniMapEntity:SetCanUseCache(False)` is called.

You got it backwards, inst.MiniMapEntity:SetCanUseCache(false) is called on placing an eye, it's intended to cache when there's no eye on it because it's not acting like a map revealing entity.

Quote

3. If the deerclopseyeball_sentryward is within the sight of player B, B can also see the cached icon. If not, the cached icon will be cleared in B's map.

And yeah, this is not supposed to happen, and it's explained above.

Edited by hoxi
  • Like 1

Share this comment


Link to comment
Share on other sites

Thanks for your reply, I indeed got it backward. I think it may not be a bug now. 

My current understanding:

  • I guess the CanUseCache(false) means that the icon remains the same when it leaves the reveal radius of the player, and it will stay the same if set CanUseCache to be true.
  • With an eyeball, there is a `globalmapicon` and the CanUseCache is false. In this case,  people who can not see the  deerclopseyeball_sentryward see the icon of the corresponding `globalmapicon` and can not see the icon of deerclopseyeball_sentryward itself.
  • Taken the eyeball off, CanUseCache is set to true. As the `globalmapicon` is removed,  people who can not see the  deerclopseyeball_sentryward can not find the icon of `globalmapicon` anymore. People near the deerclopseyeball_sentryward can see and cache the icon of deerclopseyeball_sentryward.

However, I still have some questions

  • Why does the `globalmapicon` also use CanUseCache(false) but can be seen at any place? This somehow contradicts with my hypothesis of the function of CanUseCache(false). 
  • I thought there may be a bug in `CanUseCache` when I was trying to fix the following bug. I hypothesize that `CanUseCache(false)` can only be called in the initialization, but I am not sure. 

Share this comment


Link to comment
Share on other sites

15 hours ago, clearlove said:

Why does the `globalmapicon` also use CanUseCache(false) but can be seen at any place? This somehow contradicts with my hypothesis of the function of CanUseCache(false). 

In general? Or in this case?

In this case it's simply because it's a fog revealer entity, and the crystallizer itself reveals stuff around it periodically.

In general? Usually they use SetDrawOverFogOfWar for them or are fog revealers, or the entity they track also reveals them.

Cache in this context implies that it only has to do with caching the icon in map fog until something reveals things around the area to update it.

I'd need to fully investigate the functionality of each case to give a more proper conclusion, but that's what I get from what I looked into for this bug report so far.

Share this comment


Link to comment
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
  • Create New...