Help me refine the system

Level 8
Joined
Apr 16, 2025
Messages
160
As you know, you can only get the cost of the first level of a research. For level 2+, you have to create a database of research costs. If your map has a lot of researches and you keep editing them for balance, you’ll most likely get confused somewhere.


So I created a simple hack-like system that retrieves the research cost.


However, I found a bug in it: the UI glitches, and all the spells inside the building turn gray if you queue multiple researches (more than one).


So my simple question is: how can I force the unit’s UI to refresh? So that its spells are no longer gray and unavailable for casting.

JASS:
function RemoveDummyResearchAbility takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = LoadUnitHandle(hashT, GetHandleId(t), 0)

    if GetUnitTypeId(u) != 0 and GetWidgetLife(u) > 0.405 then
        call UnitRemoveAbilityBJ('A09R', u)
    endif

    call FlushChildHashtable(hashT, GetHandleId(t))
    call DestroyTimer(t)

    set t = null
    set u = null
endfunction


function AddDummyResearchSpell takes unit u returns nothing
    local timer t = CreateTimer()

    call UnitAddAbilityBJ('A09R', u)
    call SaveUnitHandle(hashT, GetHandleId(t), 0, u)
    call TimerStart(t, 0.03, false, function RemoveDummyResearchAbility)

    set t = null
endfunction

function Trig_ResearchFinish1_Actions takes nothing returns nothing 
    local unit u = GetTriggerUnit()
    local player p = GetOwningPlayer(u)
    local integer researchId = GetResearched()
    local integer currentLevel = GetPlayerTechCount(p, researchId, true)
    local integer goldBefore
    local integer goldAfter
    local integer cost

    if GetUnitAbilityLevel(u, 'A09R') > 0 then
        set u = null
        set p = null
        return
    endif

    call SetPlayerTechResearched(p, researchId, currentLevel - 1)

    set goldBefore = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
    call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, goldBefore + 100000)
    set goldBefore = goldBefore + 100000

    call AddDummyResearchSpell(u)
    call IssueUpgradeOrderByIdBJ(u, researchId)

    set goldAfter = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
    set cost = goldBefore - goldAfter

    call SetPlayerTechResearched(p, researchId, currentLevel)
    call AdjustPlayerStateBJ(cost - 100000, p, PLAYER_STATE_RESOURCE_GOLD)

    set value[PDArr[GetPlayerId(p)]] = value[PDArr[GetPlayerId(p)]] + cost
    call Update_Value_Scoreboard(GetPlayerId(p))

    set u = null
    set p = null
endfunction
 
Last edited:
All good, I figured out the problem. I just did everything through a dummy unit - it actually turned out to be even simpler.

JASS:
function Trig_ResearchFinish1_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local player p = GetOwningPlayer(u)
    local integer researchId = GetResearched()
    local integer currentLevel = GetPlayerTechCount(p, researchId, true)
    local integer goldBefore
    local integer cost
    local unit dummy
    if GetUnitAbilityLevel(u, 'A09R') > 0 then
        set u = null
        set p = null
        return
    endif
    call SetPlayerTechResearched(p, researchId, currentLevel - 1)
    set goldBefore = GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
    call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, goldBefore + 100000)
    set dummy = CreateUnit(p, GetUnitTypeId(u), GetUnitX(u), GetUnitY(u), 0)
    call UnitAddAbilityBJ('A09R', dummy)
    call ShowUnit(dummy, false)
    call IssueUpgradeOrderByIdBJ(dummy, researchId)
    set cost = (goldBefore + 100000) - GetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD)
    call RemoveUnit(dummy)
    call SetPlayerTechResearched(p, researchId, currentLevel)
    call SetPlayerState(p, PLAYER_STATE_RESOURCE_GOLD, goldBefore)
    set value[PDArr[GetPlayerId(p)]] = value[PDArr[GetPlayerId(p)]] + cost
    call Update_Value_Scoreboard(GetPlayerId(p))
    set u = null
    set p = null
    set dummy = null
endfunction
 
Back
Top